Qt界面中的子窗口实现鼠标拖动边缘改变大小以及移动(完整demo代码)

目录

效果

拖拽

移动​编辑

实现

 DragResizeWgt类.h文件

DragResizeWgt类.cpp文件 

使用

 testwidget窗口.ui文件

testwidget窗口.h文件

testwidget窗口.cpp文件

参考


效果

想要的效果就是类似于QT IDE中的效果,可以拖动边缘改变大小,用户自身可以调整一些窗口的布局,方便使用,如下所示:

demo完成后,经测试达到的效果,如下所示:

拖拽

移动

如果你想要的是这样的效果,无需多言,上代码。

实现

这是一个自定义的窗口类,需要重写窗口的一些函数,如下所示:

    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);

 DragResizeWgt类.h文件

#ifndef DRAGRESIZEWGT_H
#define DRAGRESIZEWGT_H

#include <QWidget>
#include <QMouseEvent>
#include <QPoint>
#include <QScreen>
#include <QPainter>
#include <QResizeEvent>
#include <QEvent>
namespace Ui {
class DragResizeWgt;
}

class DragResizeWgt : public QWidget
{
    Q_OBJECT
    enum DIRECTION{
        nodir,
        top = 0x01,
        bottom = 0x02,
        left = 0x04,
        right = 0x08,
        topLeft = 0x01 | 0x04,
        topRight = 0x01 | 0x08,
        bottomLeft = 0x02 | 0x04,
        bottomRight = 0x02 | 0x08};
public:
    explicit DragResizeWgt(QWidget *parent = nullptr);
    ~DragResizeWgt();
signals:
    void sizeChange();
public:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);
    bool eventFilter(QObject *watch, QEvent *event);
    void setEdgeBeReSized(const bool& resizeableTop, const bool& resizeableBottom, const bool& resizeableRight, const bool& resizeableLeft);
    void setIsRepositioning(const bool& reposition);
private:
    void checkEdge();
private:
    Ui::DragResizeWgt *ui;

    QPoint m_startCursor;

    int m_nLeftOff = 0;//鼠标开始拖拽时子窗口左边相对父窗口左边的距离
    int m_nRightOff = 0;//鼠标开始拖拽时子窗口右边相对父窗口左边的距离
    int m_nTopOff = 0;//鼠标开始拖拽时子窗口上边相对父窗口上边的距离
    int m_nBottomOff = 0;//鼠标开始拖拽时子窗口下边相对父窗口上边的距离

    QPoint dragPosition;   //鼠标拖动的位置
    int    edgeMargin = 4;     //鼠标检测的边缘距离
    DIRECTION resizeDir; //更改尺寸的方向

    bool m_resizing;
    bool m_repositioning;
    //帮助判断是否需要激活边框可变化大小
    bool m_resizeableTop;
    bool m_resizeableBottom;
    bool m_resizeableRight;
    bool m_resizeableLeft;
};

#endif // DRAGRESIZEWGT_H

DragResizeWgt类.cpp文件 

#include "DragResizeWgt.h"
#include "ui_DragResizeWgt.h"
#include <QDebug>
#include "Windows.h"
#include <QMouseEvent>
#include <QObject>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#define min(a,b) ((a)<(b)? (a) :(b))
#define max(a,b) ((a)>(b)? (a) :(b))

DragResizeWgt::DragResizeWgt(QWidget *parent) :
    QWidget(parent),ui(new Ui::DragResizeWgt),
    resizeDir(nodir), m_resizing(false),m_repositioning(false),
    m_resizeableTop(true), m_resizeableBottom(true),
    m_resizeableRight(true), m_resizeableLeft(true)
{
    ui->setupUi(this);
    this->setObjectName("DragResizeWgt");

    //注意:一定要设置一个最小的宽高奥,要不会被拖到看不见,默认最小(0,0)
    setMinimumSize(100, 100);

    //一定一定要有这句话奥,这是能捕捉到这个窗口鼠标事件的关键,还有一点需要特别注意,如果这个窗口上会叠加其他的widget或者控件,对应的子UI也需要调用setMouseTracking这个函数
    this->setMouseTracking(true);

    //鼠标事件过滤器,来处理父窗口与子窗口的事件关系,不能互相干扰,后续会十分用得到
    setAttribute(Qt::WA_NoMousePropagation);
    installEventFilter(this);
    // QVBoxLayout *layout = new QVBoxLayout(this);
    // QLabel *label = new QLabel("Resizable and Draggable Widget", this);
    // layout->addWidget(label);

    edgeMargin = 4;        //设置检测边缘为4
    resizeDir = nodir;   //初始化检测方向为无

    setEdgeBeReSized(false,true,true,false);
    // setEdgeBeReSized(true,true,true,true);
    setLayout(new QHBoxLayout);
}

DragResizeWgt::~DragResizeWgt() = default;

void DragResizeWgt::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)  //每当按下鼠标左键就记录一下位置
    {
        dragPosition = event->globalPos() - frameGeometry().topLeft();  //获得鼠标按键位置相对窗口左上面的位置
        m_startCursor = event->globalPos();

        m_nLeftOff = frameGeometry().left();
        m_nRightOff = frameGeometry().right() + 1;
        m_nTopOff = frameGeometry().top();
        m_nBottomOff = frameGeometry().bottom() + 1;
        qDebug() << "mousePressEvent" << dragPosition << m_startCursor << m_nLeftOff << m_nRightOff << m_nTopOff << m_nBottomOff;
    }
}

void DragResizeWgt::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton)//如果左键是按下的
    {
        if(resizeDir == nodir)//鼠标未放置在边缘处,进行窗口整体拖动处理
        {
            if(m_repositioning)
            {
                move(event->globalPos() - dragPosition);
            }
        }
        else//拖拽边缘,根据拖拽方向进行大小调整
        {

            int ptop,pbottom,pleft,pright;
            ptop = m_nTopOff;
            pbottom = m_nBottomOff;
            pleft = m_nLeftOff;
            pright = m_nRightOff;
            //这里获取父窗口的大小,如果没有则获取全局可用的屏幕大小
            QRect parentRect = parentWidget() ? parentWidget()->rect() : QApplication::primaryScreen()->availableGeometry();
            if(resizeDir & top)//拖拽顶部上下变化
            {
                //计算根据当前鼠标位置与拖拽偏移量计算当前top的位置
                ptop = m_nTopOff-(m_startCursor.ry()- event->globalY());
                qDebug() << "#########top position" << ptop << m_nTopOff << m_startCursor.ry() << event->globalY();
                if(ptop < 0)
                {
                    ptop = parentRect.height() - this->maximumHeight();
                }
                else{
                    if(this->height() <= minimumHeight())//进行极端高度最小的处理
                    {
                        ptop = min(m_nBottomOff-minimumHeight(),ptop);
                        qDebug() << "this->height() >= minimumHeight()" << ptop  << m_nBottomOff << minimumHeight();
                    }
                    else if(this->height() >= maximumHeight())//进行极端高度最大的处理
                    {
                        ptop = max(m_nBottomOff-maximumHeight(),ptop);
                        qDebug() << "this->height() >= maximumHeight()" << ptop << m_nBottomOff << maximumHeight();
                    }
                }
            }
            else if(resizeDir & bottom)//拖拽底部上下变化
            {
                //计算根据当前鼠标位置与拖拽偏移量计算当前bottom的位置
                pbottom = m_nBottomOff +(event->globalY()-m_startCursor.ry());
                if(pbottom > parentRect.bottom())
                {
                    pbottom = this->maximumHeight();
                }else{
                    if(this->height()<minimumHeight())//进行极端高度最小的处理
                    {
                        pbottom = m_nTopOff+minimumHeight();
                    }
                    else if(this->height()>maximumHeight())//进行极端高度最大的处理
                    {
                        pbottom = m_nTopOff+maximumHeight();
                    }
                }
            }

            if(resizeDir & left)//拖拽左侧左右变化
            {
                //计算根据当前鼠标位置与拖拽偏移量计算当前left的位置
                pleft = m_nLeftOff-(m_startCursor.rx() - event->globalX());
                if(pleft < 0)
                {
                    pleft = 0;
                }else{
                    if(this->width()<= minimumWidth())//进行极端宽度最小的处理
                    {
                        pleft = min(pleft,m_nRightOff- minimumWidth());
                    }
                    else if(this->width() >= maximumWidth())//进行极端宽度最大的处理
                    {
                        pleft = max(m_nRightOff- maximumWidth(),pleft);
                    }
                }
            }
            else if(resizeDir & right)//拖拽右侧左右变化
            {
                //计算根据当前鼠标位置与拖拽偏移量计算当前right的位置
                pright = m_nRightOff + (event->globalX()-m_startCursor.rx());
                if(pright > parentRect.right())
                {
                    pright = parentRect.right();
                }
                if(this->width()<minimumWidth())//进行极端宽度最小的处理
                {
                    pright = m_nLeftOff+minimumWidth();
                }
                else if(this->width()> this->maximumWidth())//进行极端宽度最大的处理
                {
                    pright = m_nLeftOff + this->maximumWidth();
                }
            }
            setGeometry(pleft,ptop,pright-pleft,pbottom-ptop);
            emit sizeChange();
        }

    }
    else checkEdge();
}

void DragResizeWgt::mouseReleaseEvent(QMouseEvent * event)
{
    // Q_UNUSED(event);
    if(resizeDir != nodir)//还原鼠标样式
    {
        checkEdge();
        emit sizeChange();
    }
}

void DragResizeWgt::paintEvent(QPaintEvent *event)
{
    // QPainter painter(this);
    // painter.fillRect(rect(), Qt::white);
    QWidget::paintEvent(event);
}

void DragResizeWgt::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    // emit sizeChange();
}

bool DragResizeWgt::eventFilter(QObject *watch, QEvent *event)
{
    //一定要加这一句,不然父窗口的event事件也会出发窗口大小的改变信号
    if(watch == parentWidget() && event->type() == QEvent::MouseButtonRelease)
    {
        event->ignore();
        return true;
    }
    // if(watch == parentWidget() && event->type() == QEvent::Resize)
    // {
    //     event->ignore();
    //     return true;
    // }
    return QWidget::eventFilter(watch, event);
}

void DragResizeWgt::setEdgeBeReSized(const bool &resizeableTop, const bool &resizeableBottom, const bool &resizeableRight, const bool &resizeableLeft)
{
    m_resizeableTop = resizeableTop;
    m_resizeableBottom =  resizeableBottom;
    m_resizeableRight = resizeableRight;
    m_resizeableLeft = resizeableLeft;
}

void DragResizeWgt::setIsRepositioning(const bool &reposition)
{
    m_repositioning = reposition;
}

void DragResizeWgt::checkEdge()
{
    QPoint pos = this->mapFromGlobal(QCursor::pos());//开始拖拽时点击控件的什么位置

    int diffLeft = pos.rx();
    int diffRight = this->width() - diffLeft;
    int diffTop = pos.ry();
    int diffBottom = this->height() - diffTop;
    QCursor tempCursor;                                    //获得当前鼠标样式,注意:只能获得当前鼠标样式然后再重新设置鼠标样式
    tempCursor = cursor();                                 //因为获得的不是鼠标指针,所以不能这样用:cursor().setXXXXX

    // qDebug() << "diffLeft" << diffLeft << "diffRight" << diffRight << "diffTop" << diffTop << "diffBottom" << diffBottom ;
    if(diffTop < edgeMargin && m_resizeableTop)
    {                              //根据 边缘距离 分类改变尺寸的方向
        if(diffLeft < edgeMargin  && m_resizeableTop && m_resizeableLeft)
        {
            resizeDir = topLeft;
            tempCursor.setShape(Qt::SizeFDiagCursor);
        }
        else if(diffRight < edgeMargin && m_resizeableTop && m_resizeableRight)
        {
            resizeDir = topRight;
            tempCursor.setShape(Qt::SizeBDiagCursor);
        }
        else
        {
            resizeDir = top;
            tempCursor.setShape(Qt::SizeVerCursor);
        }
    }
    else if(diffBottom < edgeMargin && m_resizeableBottom)
    {
        if(diffLeft < edgeMargin && m_resizeableBottom && m_resizeableLeft)
        {
            resizeDir = bottomLeft;
            tempCursor.setShape(Qt::SizeBDiagCursor);
        }
        else if(diffRight < edgeMargin && m_resizeableBottom && m_resizeableRight)
        {
            resizeDir = bottomRight;
            tempCursor.setShape(Qt::SizeFDiagCursor);
        }
        else
        {
            resizeDir = bottom;
            tempCursor.setShape(Qt::SizeVerCursor);
        }
    }
    else if(diffLeft < edgeMargin && m_resizeableLeft)
    {
        resizeDir = left;
        tempCursor.setShape(Qt::SizeHorCursor);
    }
    else if(diffRight < edgeMargin && m_resizeableRight)
    {
        resizeDir = right;
        tempCursor.setShape(Qt::SizeHorCursor);
    }
    else
    {
        resizeDir = nodir;
        tempCursor.setShape(Qt::ArrowCursor);
    }

    setCursor(tempCursor);
}



使用

新建一个主界面窗口testwidget,用于创建主界面包含QWidget和DragResizeWgt共同存在的情况

其中widget_6为底部窗口,widget_5为顶部窗口

注意,我这里右边的窗口类中,我将widget_6和widget提升为了DragResizeWgt窗口类。

 testwidget窗口.ui文件

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>testwidget</class>
 <widget class="QWidget" name="testwidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>662</width>
    <height>549</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_2">
   <property name="spacing">
    <number>0</number>
   </property>
   <property name="leftMargin">
    <number>0</number>
   </property>
   <property name="topMargin">
    <number>0</number>
   </property>
   <property name="rightMargin">
    <number>0</number>
   </property>
   <property name="bottomMargin">
    <number>0</number>
   </property>
   <item>
    <widget class="QWidget" name="widget_8" native="true">
     <layout class="QVBoxLayout" name="verticalLayout">
      <property name="spacing">
       <number>0</number>
      </property>
      <property name="leftMargin">
       <number>0</number>
      </property>
      <property name="topMargin">
       <number>0</number>
      </property>
      <property name="rightMargin">
       <number>0</number>
      </property>
      <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
       <widget class="QWidget" name="widget_5" native="true">
        <property name="minimumSize">
         <size>
          <width>0</width>
          <height>50</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
          <width>16777215</width>
          <height>50</height>
         </size>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QWidget" name="widget_7" native="true">
        <property name="styleSheet">
         <string notr="true">background-color: rgb(170, 85, 255);</string>
        </property>
        <layout class="QHBoxLayout" name="horizontalLayout_2">
         <property name="spacing">
          <number>0</number>
         </property>
         <property name="leftMargin">
          <number>0</number>
         </property>
         <property name="topMargin">
          <number>0</number>
         </property>
         <property name="rightMargin">
          <number>0</number>
         </property>
         <property name="bottomMargin">
          <number>0</number>
         </property>
         <item>
          <widget class="DragResizeWgt" name="widget" native="true">
           <property name="styleSheet">
            <string notr="true"/>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QWidget" name="widget_4" native="true">
           <property name="styleSheet">
            <string notr="true">background-color: rgb(0, 0, 127);</string>
           </property>
          </widget>
         </item>
        </layout>
       </widget>
      </item>
     </layout>
    </widget>
   </item>
   <item>
    <widget class="DragResizeWgt" name="widget_6" native="true">
     <property name="styleSheet">
      <string notr="true">background-color: rgb(255, 85, 127);</string>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <property name="spacing">
       <number>0</number>
      </property>
     </layout>
    </widget>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>DragResizeWgt</class>
   <extends>QWidget</extends>
   <header>dragresizewgt.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

testwidget窗口.h文件

#ifndef TESTWIDGET_H
#define TESTWIDGET_H

#include <QWidget>
#include <QMouseEvent>
namespace Ui {
class testwidget;
}

class testwidget : public QWidget
{
    Q_OBJECT

public:
    explicit testwidget(QWidget *parent = nullptr);
    ~testwidget();

public:
    void resizeEvent(QResizeEvent *event);
private:
    Ui::testwidget *ui;
};

#endif // TESTWIDGET_H

testwidget窗口.cpp文件

#include "testwidget.h"
#include "qdebug.h"
#include "ui_testwidget.h"
#include "dragresizewgt.h"
#include <QPushButton>
testwidget::testwidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::testwidget)
{
    ui->setupUi(this);
    // DragResizeWgt *w = new DragResizeWgt(this);
    // w->resize(400,400);
    // w->setStyleSheet("background-color: rgb(255, 255, 0);");
    // w->show();
    // this->setMaximumSize(1920,1080);
    this->setMouseTracking(true);
    this->setMinimumSize(480,270);

    ui->widget->setEdgeBeReSized(false,false,true,false);
    // ui->widget->setWgtMaxmumSize(300,800);
    ui->widget->setMinimumSize(100,0);
    // ui->widget_4->setEdgeBeReSized(false,false,false,true);
    ui->widget_6->setEdgeBeReSized(true,false,false,false);
    ui->widget_6->setMinimumSize(0,100);
    // ui->widget_6->setWgtMaxmumSize(1000,800);
    // ui->widget->setStyleSheet("background-color: rgb(20, 20, 255);");
    QWidget *childWidget3 = new QWidget;
    childWidget3->setMouseTracking(true);
    childWidget3->setStyleSheet("background-color: rgb(255, 12, 128);");
    childWidget3->setMouseTracking(true);
    ui->widget->layout()->addWidget(childWidget3);
    ui->widget->layout()->setContentsMargins(0,0,0,0);
    ui->widget->layout()->setSpacing(0);
    connect(ui->widget, &DragResizeWgt::sizeChange, [=](){
        qDebug() << "this->width()" << this->width() << "ui->widget->width()"<< ui->widget->width();
        int remainingWidth = this->width() -  ui->widget->width();
        ui->widget_4->setFixedWidth(remainingWidth);
    });
    connect(ui->widget_6, &DragResizeWgt::sizeChange, [=](){
        qDebug() << "this->width()" << this->height() << "ui->widget->height()"<< ui->widget_6->height();
        int remainingHeight= this->height() -  ui->widget_6->height();
        ui->widget_8->setFixedHeight(remainingHeight);
        ui->widget_4->setFixedHeight(remainingHeight);
    });
    QWidget *childWidget1 = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout(this);
    QPushButton *label = new QPushButton("Resizable and Draggable Widget", childWidget1);
    layout->addWidget(label);
    childWidget1->setLayout(layout);
    connect(label,  &QPushButton::clicked, [](){
        qDebug() << "pushbutton clicked";
    });
    childWidget1->setMouseTracking(true);
    childWidget1->setStyleSheet("background-color: rgb(85, 85, 255);");
    QWidget *childWidget2 = new QWidget;
    childWidget2->setMouseTracking(true);
    childWidget2->setStyleSheet("background-color: rgb(85, 20, 255);");
    ui->widget_6->layout()->addWidget(childWidget1);
    ui->widget_6->layout()->addWidget(childWidget2);
    ui->widget_6->layout()->setContentsMargins(0,0,0,0);
    ui->widget_6->layout()->setSpacing(0);


    ui->widget->setIsRepositioning(true);
}

testwidget::~testwidget()
{
    delete ui;
}

// void testwidget::mousePressEvent(QMouseEvent *event)
// {

// }

// void testwidget::mouseReleaseEvent(QMouseEvent *event)
// {

// }

void testwidget::resizeEvent(QResizeEvent *event)
{
    qDebug() << "resizeEvent";
    ui->widget_6->setMaximumSize(this->width(),this->height()*0.7);
    ui->widget_8->setMinimumWidth(0);
    ui->widget_8->setMaximumWidth(this->width());
    ui->widget_8->setMinimumHeight(0);
    ui->widget_8->setMaximumHeight(this->height() - ui->widget_6->height());
    ui->widget_4->setMaximumWidth(this->width()*0.9);
    ui->widget->setMaximumSize(this->width()*0.9,this->height() - ui->widget_5->height());
}

最后在main函数中show()

    testwidget w;
    w.show();

参考

源于对这篇文章的参考,调试与修改

https://blog.csdn.net/weixin_40425059/article/details/116495403

如有什么别的问题可以留言,谢谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/762559.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt:7.QWidget属性介绍(cursor属性-光标形状、font属性-控件文本样式、tooltip属性-控件提示信息)

目录 一、cursor属性-光标形状&#xff1a; 1.1cursor属性介绍&#xff1a; 1.2获取当前光标形状——cursor()&#xff1a; 1.3 设置光标的形状——setCursor()&#xff1a; 1.4 设置自定义图片为光标&#xff1a; 二、font属性-控件文本样式&#xff1a; 2.1font属性介绍…

一句话介绍什么是AI智能体?

什么是AI智能体&#xff1f; 一句话说就是利用各种AI的功能的api组合&#xff0c;完成你想要的结果。 例如你希望完成一个关于主题为啤酒主题的小红书文案图片&#xff0c;那么它就可以完成 前面几个步骤类似automa的组件&#xff0c;最后生成一个结果。

信息学奥赛初赛天天练-41-CSP-J2021基础题-n个数取最大、树的边数、递归、递推、深度优先搜索应用

PDF文档公众号回复关键字:20240701 2021 CSP-J 选择题 单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 4.以比较作为基本运算&#xff0c;在N个数中找出最大数&#xff0c;最坏情况下所需要的最少比…

汽车内饰塑料件光照老化实验箱

塑料件光照老化实验箱概述 塑料件光照老化实验箱&#xff0c;又称为氙灯老化试验箱&#xff0c;是一种模拟自然光照条件下塑料材料老化情况的实验设备。它通过内置的氙灯或其他光源&#xff0c;产生接近自然光的紫外线辐射&#xff0c;以此来加速塑料及其他材料的光老化过程。…

进程,线程,虚拟内存,交换技术

参考资料&#xff1a; 参考视频1https://www.bilibili.com/video/BV1Hs421M78w/?spm_id_from333.999.0.0&vd_source97411b9a8288d7869f5363f72b0d7613 参考视频2https://www.bilibili.com/video/BV1jE411W7e8/?spm_id_from333.337.search-card.all.click&vd_source…

【创建者模式-建造者模式】

概要 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 建造者模式包含以下角色 抽象建造者类&#xff08;Builder&#xff09;&#xff1a;这个接口规定要实现复杂对象的那些部分的创建&#xff0c;并不涉及具体的部件对象的创建。具体建…

使用explain优化慢查询的业务场景分析

问&#xff1a;你最害怕的事情是什么&#xff1f;答&#xff1a;搓澡问&#xff1a;为什么&#xff1f;答&#xff1a;因为有些人一旦错过&#xff0c;就不在了 Explain 这个词在不同的上下文中有不同的含义。在数据库查询优化的上下文中&#xff0c;“EXPLAIN” 是一个常用的 …

基于PHP的初中数学题库管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的初中数学题库管理系统 一 介绍 此初中数学题库管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;系统角色分为学生&#xff0c;教师和管理员。(附带参考设计文档) 技术栈&#xff1a;phpmysqlphpstudyvscode 二 功能 …

YOLOv10改进教程|C2f-CIB加入注意力机制

一、 导读 论文链接&#xff1a;https://arxiv.org/abs/2311.11587 代码链接&#xff1a;GitHub - CV-ZhangXin/AKConv YOLOv10训练、验证及推理教程 二、 C2f-CIB加入注意力机制 2.1 复制代码 打开ultralytics->nn->modules->block.py文件&#xff0c;复制SE注意力机…

Android 大话binder通信

戳蓝字“牛晓伟”关注我哦&#xff01; 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章 由于 Android 大话binder通信(上) 和 Android 大话binder通信(下) 分为两篇阅读体验不好&#xff0c;顾合并为一篇。 本文摘要 用故事的方式把binder通信的整个过程都描述…

分享一个在 WinForm 桌面程序中使用进度条展示报表处理进度的例子,提升用户体验

前言 在有些比较消耗时间的业务场景中&#xff0c;比如生成报表等&#xff0c;如果没有在操作的过程中向用户反馈操作进度&#xff0c;会让用户以为程序 “死” 掉了&#xff0c;用户体验非常不好。 WinForm 桌面程序项目与 Console 项目不一样&#xff0c;如果 Console 项目…

C++ initializer_list类型推导

目录 initializer_list C自动类型推断 auto typeid decltype initializer_list<T> C支持统一初始化{ }&#xff0c;出现了一个新的类型initializer_list<T>&#xff0c;一切类型都可以用列表初始化。提供了一种更加灵活、安全和明确的方式来初始化对象。 class…

MIT6.s081 2021 Lab Page tables

Speed up system calls 思路 题目要求在每个进程初始化时为它的页表插入一个页表项&#xff0c;内核通过这样预先缓存页表项的操作&#xff0c;来加速特定系统调用的执行速度。 由于前不久刚过完一遍《OSTEP》&#xff0c;因此我认为自己对页表机制还算比较熟悉&#xff0c;…

Open AI Stream Completion Set Variable Inside Function PHP With Openai-php SDK

题意&#xff1a;使用 OpenAI 的 PHP SDK&#xff08;例如 openai-php&#xff09;来在函数内部设置和完成一个流&#xff08;stream&#xff09;相关的变量 问题背景&#xff1a; How to set variable inside this openai-php sdk function in stream completion ? I am usi…

【笔记】手工部署之linux中开放已安装的mysql与tomcat端口

在需要打包的springboot项目中输入mvn clean package 在target下面获得jar包 进入linux中你想要该jar包存在的位置 将jar包上传至linux中 此时在浏览器中输入linux的ip地址&#xff1a;端口号/mapping路径为404 故&#xff1a; 在linux中另开一个标签页 检查mysql和tomcat已…

JavaFX布局-BorderPane

JavaFX布局-BorderPane 实现方式Java实现FXML实现 综合案例 将容器空间分成五个区域&#xff1a;顶部&#xff08;Top&#xff09;、底部&#xff08;Bottom&#xff09;、左侧&#xff08;Left&#xff09;、右侧&#xff08;Right&#xff09;和中心&#xff08;Center&#…

Java案例找素数(三种方法)

目录 一&#xff1a;问题&#xff1a; 二&#xff1a;思路分析&#xff1a; 三&#xff1a;具体代码&#xff1a; 四&#xff1a;运行结果&#xff1a; 一&#xff1a;问题&#xff1a; 二&#xff1a;思路分析&#xff1a; 三&#xff1a;具体代码&#xff1a; Ⅰ&#xf…

03 _ 类型基础(2):动态类型与静态类型

静态类型语言与动态类型语言 通俗定义 静态类型语言&#xff1a;在编译 阶段确定所有变量的类型 动态类型语言&#xff1a;在执行阶段确定所有变量的类型 Javascript 与 C 对比 静态类型与动态类型对比 其他定义 强类型语言&#xff1a;不允许程序在发生错误后继续执行 语…

【STM32】温湿度采集与OLED显示

一、任务要求 1. 学习I2C总线通信协议&#xff0c;使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集&#xff0c;并将采集的温度-湿度值通过串口输出。 任务要求&#xff1a; 1&#xff09;解释什么是“软件I2C”和“硬件I2C”&#xff1f;&#xff08;阅读野火配…

视频号视频怎么下载保存到手机,视频号视频如何下载到电脑本地

在数字化浪潮的推动下&#xff0c;视频号成为了我们获取信息、分享生活的重要平台。但有时候&#xff0c;我们遇到一些精彩的内容&#xff0c;想要保存下来以便日后观看&#xff0c;却发现视频号并不提供直接的下载功能。下面我就来为大家详细介绍视频号视频下载的方法&#xf…
最新文章