QT 基于QScrollArea的界面嵌套移动

在实际的应用场景中,经常会出现软件界面战场图大于实际窗体大小,利用QScrollArea可以为widget窗体添加滚动条,可以实现小窗体利用滚动条显示大界面需求。实现如下:

  • QT创建一个qWidget界面

       QT 基于QScrollArea的界面嵌套移动

  • 在ui界面中利用QT自带的widget控件布局一个如下图所示的层叠关系,widget_2界面大小需大于widget大小

       QT 基于QScrollArea的界面嵌套移动

  • 界面布局好后,将widget_2提升为类,提升之前需为工程新添加一个设计界面类,添加完之后,将widget_2提升为类类名和前面新添加的设计界面类名一致

       QT 基于QScrollArea的界面嵌套移动

 

       QT 基于QScrollArea的界面嵌套移动

  • 源码实现如下
  patchwindow.h
QT 基于QScrollArea的界面嵌套移动

 1 #ifndef PATCHWINDOW_H  2 #define PATCHWINDOW_H  3   4 #include <QDebug>  5 #include <QPainter>  6 #include <QWidget>  7 #include <QMouseEvent>  8 #include <QStyleOption>  9 #include <QPaintEvent> 10  11 enum CursorRegion{ 12     NONE, 13     TOPLEFT, 14     TOPRIGHT, 15     BOTTOMRIGHT, 16     BOTTOMLEFT 17 }; 18  19 namespace Ui { 20 class Patchwindow; 21 } 22  23 class Patchwindow : public QWidget 24 { 25     Q_OBJECT 26  27 public: 28     explicit Patchwindow(QWidget *parent = 0); 29     ~Patchwindow(); 30     CursorRegion getCursorRegion(QPoint); 31  32 public: 33     int borderWidth; 34     int handleSize; 35  36     bool mousePressed; 37     QPoint previousPos; 38  39 private: 40     Ui::Patchwindow *ui; 41  42 protected: 43     void mousePressEvent(QMouseEvent*); 44     void mouseReleaseEvent(QMouseEvent*); 45     void mouseMoveEvent(QMouseEvent*); 46  47 signals: 48     void send_widget_rx_ry(int rx,int ry); 49 }; 50  51 #endif // PATCHWINDOW_H

View Code

 patchwindow.cpp
QT 基于QScrollArea的界面嵌套移动

 1 #include "patchwindow.h"  2 #include "ui_patchwindow.h"  3   4 Patchwindow::Patchwindow(QWidget *parent) :  5     QWidget(parent),  6     ui(new Ui::Patchwindow)  7 {  8     ui->setupUi(this);  9  10     this->setMouseTracking(true); 11  12     setFocusPolicy(Qt::StrongFocus); 13  14     mousePressed = false; 15     borderWidth = 1; 16     handleSize = 8; 17  18 } 19  20 Patchwindow::~Patchwindow() 21 { 22     delete ui; 23 } 24  25  26 //设置鼠标形状 27 CursorRegion Patchwindow::getCursorRegion(QPoint pos) 28 { 29     if (pos.x() > 0 && pos.x() < (handleSize + borderWidth) && 30         pos.y() > 0 && pos.y() < (handleSize + borderWidth)  ){ 31         if (this->hasFocus()) 32             this->setCursor(QCursor(Qt::SizeFDiagCursor)); 33         return CursorRegion::TOPLEFT; 34     } 35  36     if (pos.x() > (this->width() - handleSize - borderWidth) && pos.x() < this->width() && 37         pos.y() > 0 && pos.y() < (handleSize + borderWidth)  ){ 38         if (this->hasFocus()) 39             this->setCursor(QCursor(Qt::SizeBDiagCursor)); 40         return CursorRegion::TOPRIGHT; 41     } 42  43     if (pos.x() > (this->width() - handleSize - borderWidth) && pos.x() < this->width() && 44         pos.y() > (this->height() - handleSize - borderWidth) && pos.y() < this->height()  ){ 45         if (this->hasFocus()) 46             this->setCursor(QCursor(Qt::SizeFDiagCursor)); 47         return CursorRegion::BOTTOMRIGHT; 48     } 49  50  51     if (pos.x() > 0 && pos.x() < (handleSize + borderWidth) && 52         pos.y() > (this->height() - handleSize - borderWidth) && pos.y() < this->height()  ){ 53         if (this->hasFocus()) 54             this->setCursor(QCursor(Qt::SizeBDiagCursor)); 55         return CursorRegion::BOTTOMLEFT; 56     } 57  58     this->setCursor(Qt::ArrowCursor); 59     return CursorRegion::NONE; 60 } 61  62 void Patchwindow::mousePressEvent(QMouseEvent *event) 63 { 64     mousePressed = true; 65     previousPos = this->mapToParent(event->pos()); 66     //qDebug()<<"previousPos = "<<previousPos; 67 } 68  69 void Patchwindow::mouseReleaseEvent(QMouseEvent*) 70 { 71     mousePressed = false; 72 } 73  74 void Patchwindow::mouseMoveEvent(QMouseEvent *event) 75 { 76     if (mousePressed){ 77         QPoint _curPos = this->mapToParent(event->pos()); 78         QPoint _offPos = _curPos - previousPos; 79         previousPos = _curPos; 80         //qDebug()<<"_offPos = "<<_offPos; 81         //qDebug()<<"_curPos = "<<_curPos; 82         emit send_widget_rx_ry(_offPos.rx(),_offPos.ry()); 83     } 84 }

View Code

 mainwindow.h
QT 基于QScrollArea的界面嵌套移动

 1 #ifndef MAINWINDOW_H  2 #define MAINWINDOW_H  3   4 #include <QMainWindow>  5 #include <QHBoxLayout>  6 #include <QDebug>  7 #include <QScrollArea>  8   9  10 namespace Ui { 11 class MainWindow; 12 } 13  14 class MainWindow : public QMainWindow 15 { 16     Q_OBJECT 17  18 public: 19     explicit MainWindow(QWidget *parent = 0); 20     ~MainWindow(); 21  22     QScrollArea *m_pScroll; 23  24  25 private: 26     Ui::MainWindow *ui; 27  28 private slots: 29     void remove_widget(int r_x,int r_y); 30  31  32 }; 33  34 #endif // MAINWINDOW_H

View Code

 mainwindow.cpp
QT 基于QScrollArea的界面嵌套移动

 1 #include "mainwindow.h"  2 #include "ui_mainwindow.h"  3 #include <QPalette>  4   5 #include <QScrollBar>  6   7 MainWindow::MainWindow(QWidget *parent) :  8     QMainWindow(parent),  9     ui(new Ui::MainWindow) 10 { 11     ui->setupUi(this); 12     //this->resize(600,600); 13  14     //给父窗体填充颜色 15     QPalette palette = ui->widget_2->palette(); 16     palette.setBrush(QPalette::Window,QBrush(QColor(61,61,61))); 17     ui->widget_2->setAutoFillBackground(true); 18     ui->widget_2->setPalette(palette); 19  20     ui->widget_2->setAttribute(Qt::WA_StyledBackground); 21     ui->widget_2->setStyleSheet("QWidget{background: black}"); 22  23     ui->widget_3->setAttribute(Qt::WA_TransparentForMouseEvents, true);//设置该层鼠标事件透明,可以设置为显示层 24  25     m_pScroll = new QScrollArea(ui->widget); 26     m_pScroll->setWidget(ui->widget_2);//给widget_2设置滚动条 27     //ui->widget_2->setMinimumSize(1500,1000);//这里注意,要比主窗体的尺寸要大,不然太小的话会留下一片空白 28  29     QHBoxLayout *pLayout = new QHBoxLayout; 30     pLayout->addWidget(m_pScroll); 31     pLayout->setMargin(0); 32     pLayout->setSpacing(0); 33     ui->widget->setLayout(pLayout); 34  35     connect(ui->widget_2,&Patchwindow::send_widget_rx_ry,this,&MainWindow::remove_widget); 36  37 } 38  39 MainWindow::~MainWindow() 40 { 41     delete ui; 42 } 43  44 void MainWindow::remove_widget(int r_x,int r_y) 45 { 46     r_y = m_pScroll->verticalScrollBar()->value()-r_y; 47     r_x = m_pScroll->horizontalScrollBar()->value()-r_x; 48  49     if((0 < r_y) | (r_y == 0)) 50     { 51         if(r_y > m_pScroll->verticalScrollBar()->maximum()) 52         { 53             r_y = m_pScroll->verticalScrollBar()->maximum(); 54         } 55     } 56     else 57     { 58         r_y = 0; 59     } 60  61     if((0 < r_x) | (r_x == 0)) 62     { 63         if(r_x > m_pScroll->horizontalScrollBar()->maximum()) 64         { 65             r_x = m_pScroll->horizontalScrollBar()->maximum(); 66         } 67     } 68     else 69     { 70         r_x = 0; 71     } 72  73     m_pScroll->verticalScrollBar()->setValue(r_y); 74     m_pScroll->horizontalScrollBar()->setValue(r_x); 75  76 }

View Code

  • 最终实现效果如下,可以通过滚轮滚动界面,也可以通过鼠标拖拽来实现界面拖拽效果:

    QT 基于QScrollArea的界面嵌套移动

    工程源码下载路径:

「ScrollArea」https://www.aliyundrive.com/s/QMf912nt86A 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。

 

发表评论

相关文章