Qt 笔记6--Qt 窗体区域拉伸移动

Qt 笔记6--Qt 窗体区域拉伸移动

很多时候,一个窗体中各子区域的大小需要动态调整,如Qt Creator主界面的项目区、类视图去、编码区、应用程序输出区等,它们之间大小调整一般通过拖动边界区域来实现的。以下为笔者通过重写mouseMoveEvent、mousePressEvent、mouseReleaseEvent等方法实现的一个简单区域拉伸移动案例,相应学习笔记贴在此处以便于后续参考。

 

1、功能介绍

以下两张图分别为Qt Creator中左右和上下区域拉伸移动的效果,本文主要为了达到类似的效果。笔者通过重写widget中的mouseMoveEvent、mousePressEvent、mouseReleaseEvent方法,根据其鼠标位置变化来确定是否更改区域的大小,从而达到区域拉伸移动的效果。

图1 左右拉伸移动

图2 上下拉伸移动

 

2、源代码

该方法比较简单,笔者使用第一行区域的下边界和第二行一列区域的右边界为触发边界,触发区间为[-5,5],代码主要包括三个源文件:widget.h、widget.cpp和main.cpp,具体源码如下:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>
#include <QKeyEvent>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

protected:

    virtual void mouseMoveEvent(QMouseEvent *event) override;
    virtual void mousePressEvent(QMouseEvent *event) override;
    virtual void mouseReleaseEvent(QMouseEvent *event) override;
    virtual void resizeEvent(QResizeEvent *event) override;

private:
    Ui::Widget *ui;
    int mousePosX;//记录有效位置的X
    int mousePosY;//记录有效位置的Y
    bool mouseFlagX = false;//记录是否可以进行左右移动
    bool mouseFlagY = false;//记录是否可以开始上下移动
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

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

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    if(mouseFlagX){
        //qDebug().noquote()<<"Moving X:"<<event->x();
        int xChanged = event->x()-mousePosX;
        ui->widget_2->resize(ui->widget_2->geometry().width()+xChanged,ui->widget_2->geometry().height());
        ui->widget_3->setGeometry(ui->widget_3->geometry().x()+xChanged,ui->widget_2->geometry().y(),ui->widget_3->geometry().width()-xChanged,ui->widget_3->geometry().height());
        mousePosX = event->x();
    }
    if(mouseFlagY){
        //qDebug().noquote()<<"Moving Y:"<<event->y();
        int yChanged = event->y()-mousePosY;
        ui->widget_1->resize(ui->widget_1->geometry().width(),ui->widget_1->geometry().height()+yChanged);
        ui->widget_2->setGeometry(ui->widget_2->geometry().x(),ui->widget_2->geometry().y()+yChanged,ui->widget_2->geometry().width(),ui->widget_2->geometry().height()-yChanged);
        ui->widget_3->setGeometry(ui->widget_3->geometry().x(),ui->widget_3->geometry().y()+yChanged,ui->widget_3->geometry().width(),ui->widget_3->geometry().height()-yChanged);
        mousePosY = event->y();
    }
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    //qDebug().noquote()<<"mousePressEvent";
    if(event->y()<=(ui->widget_1->geometry().height()+5) && event->y()>=(ui->widget_1->geometry().height()-5))
    {
        mousePosY = event->y();
        mouseFlagY = true;
    }
    if(event->x()<=(ui->widget_2->geometry().width()+5) && event->x()>=(ui->widget_2->geometry().width()-5))
    {
        mousePosX = event->x();
        mouseFlagX = true;
    }
}

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    //qDebug().noquote()<<"mouseReleaseEvent";
    mouseFlagX = false;
    mouseFlagY = false;
}

void Widget::resizeEvent(QResizeEvent *event)
{
    QSize qsize = this->size();
    ui->widget_1->resize(qsize.width(),ui->widget_1->height());
    ui->widget_2->resize(ui->widget_2->width(),qsize.height()-ui->widget_1->height()-2);
    ui->widget_3->resize(qsize.width() - ui->widget_2->width()+2,qsize.height()-ui->widget_1->height()-2);
}

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

3、测试结果

如下gif图片所示,触发区间为第一行区域下边界和第二行第一列的右边界;此处只提供了一种触发方法,也可以根据需要自定义其它类型的触发效果。

4、说明

以上代码默认测试环境为Qt 5.7,测试系统为Windows7 x64

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昕光xg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值