Qt基于QScrollArea實(shí)現(xiàn)界面嵌套移動(dòng)
在實(shí)際的應(yīng)用場(chǎng)景中,經(jīng)常會(huì)出現(xiàn)軟件界面戰(zhàn)場(chǎng)圖大于實(shí)際窗體大小,利用QScrollArea可以為widget窗體添加滾動(dòng)條,可以實(shí)現(xiàn)小窗體利用滾動(dòng)條顯示大界面需求。實(shí)現(xiàn)如下:
QT創(chuàng)建一個(gè)qWidget界面
在ui界面中利用QT自帶的widget控件布局一個(gè)如下圖所示的層疊關(guān)系,widget_2界面大小需大于widget大小
界面布局好后,將widget_2提升為類,提升之前需為工程新添加一個(gè)設(shè)計(jì)界面類,添加完之后,將widget_2提升為類類名和前面新添加的設(shè)計(jì)界面類名一致
源碼實(shí)現(xiàn)如下
patchwindow.h
#ifndef PATCHWINDOW_H #define PATCHWINDOW_H #include <QDebug> #include <QPainter> #include <QWidget> #include <QMouseEvent> #include <QStyleOption> #include <QPaintEvent> enum CursorRegion{ NONE, TOPLEFT, TOPRIGHT, BOTTOMRIGHT, BOTTOMLEFT }; namespace Ui { class Patchwindow; } class Patchwindow : public QWidget { Q_OBJECT public: explicit Patchwindow(QWidget *parent = 0); ~Patchwindow(); CursorRegion getCursorRegion(QPoint); public: int borderWidth; int handleSize; bool mousePressed; QPoint previousPos; private: Ui::Patchwindow *ui; protected: void mousePressEvent(QMouseEvent*); void mouseReleaseEvent(QMouseEvent*); void mouseMoveEvent(QMouseEvent*); signals: void send_widget_rx_ry(int rx,int ry); }; #endif // PATCHWINDOW_H
patchwindow.cpp
#include "patchwindow.h" #include "ui_patchwindow.h" Patchwindow::Patchwindow(QWidget *parent) : QWidget(parent), ui(new Ui::Patchwindow) { ui->setupUi(this); this->setMouseTracking(true); setFocusPolicy(Qt::StrongFocus); mousePressed = false; borderWidth = 1; handleSize = 8; } Patchwindow::~Patchwindow() { delete ui; } //設(shè)置鼠標(biāo)形狀 CursorRegion Patchwindow::getCursorRegion(QPoint pos) { if (pos.x() > 0 && pos.x() < (handleSize + borderWidth) && pos.y() > 0 && pos.y() < (handleSize + borderWidth) ){ if (this->hasFocus()) this->setCursor(QCursor(Qt::SizeFDiagCursor)); return CursorRegion::TOPLEFT; } if (pos.x() > (this->width() - handleSize - borderWidth) && pos.x() < this->width() && pos.y() > 0 && pos.y() < (handleSize + borderWidth) ){ if (this->hasFocus()) this->setCursor(QCursor(Qt::SizeBDiagCursor)); return CursorRegion::TOPRIGHT; } if (pos.x() > (this->width() - handleSize - borderWidth) && pos.x() < this->width() && pos.y() > (this->height() - handleSize - borderWidth) && pos.y() < this->height() ){ if (this->hasFocus()) this->setCursor(QCursor(Qt::SizeFDiagCursor)); return CursorRegion::BOTTOMRIGHT; } if (pos.x() > 0 && pos.x() < (handleSize + borderWidth) && pos.y() > (this->height() - handleSize - borderWidth) && pos.y() < this->height() ){ if (this->hasFocus()) this->setCursor(QCursor(Qt::SizeBDiagCursor)); return CursorRegion::BOTTOMLEFT; } this->setCursor(Qt::ArrowCursor); return CursorRegion::NONE; } void Patchwindow::mousePressEvent(QMouseEvent *event) { mousePressed = true; previousPos = this->mapToParent(event->pos()); //qDebug()<<"previousPos = "<<previousPos; } void Patchwindow::mouseReleaseEvent(QMouseEvent*) { mousePressed = false; } void Patchwindow::mouseMoveEvent(QMouseEvent *event) { if (mousePressed){ QPoint _curPos = this->mapToParent(event->pos()); QPoint _offPos = _curPos - previousPos; previousPos = _curPos; //qDebug()<<"_offPos = "<<_offPos; //qDebug()<<"_curPos = "<<_curPos; emit send_widget_rx_ry(_offPos.rx(),_offPos.ry()); } }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QHBoxLayout> #include <QDebug> #include <QScrollArea> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); QScrollArea *m_pScroll; private: Ui::MainWindow *ui; private slots: void remove_widget(int r_x,int r_y); }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPalette> #include <QScrollBar> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //this->resize(600,600); //給父窗體填充顏色 QPalette palette = ui->widget_2->palette(); palette.setBrush(QPalette::Window,QBrush(QColor(61,61,61))); ui->widget_2->setAutoFillBackground(true); ui->widget_2->setPalette(palette); ui->widget_2->setAttribute(Qt::WA_StyledBackground); ui->widget_2->setStyleSheet("QWidget{background: black}"); ui->widget_3->setAttribute(Qt::WA_TransparentForMouseEvents, true);//設(shè)置該層鼠標(biāo)事件透明,可以設(shè)置為顯示層 m_pScroll = new QScrollArea(ui->widget); m_pScroll->setWidget(ui->widget_2);//給widget_2設(shè)置滾動(dòng)條 //ui->widget_2->setMinimumSize(1500,1000);//這里注意,要比主窗體的尺寸要大,不然太小的話會(huì)留下一片空白 QHBoxLayout *pLayout = new QHBoxLayout; pLayout->addWidget(m_pScroll); pLayout->setMargin(0); pLayout->setSpacing(0); ui->widget->setLayout(pLayout); connect(ui->widget_2,&Patchwindow::send_widget_rx_ry,this,&MainWindow::remove_widget); } MainWindow::~MainWindow() { delete ui; } void MainWindow::remove_widget(int r_x,int r_y) { r_y = m_pScroll->verticalScrollBar()->value()-r_y; r_x = m_pScroll->horizontalScrollBar()->value()-r_x; if((0 < r_y) | (r_y == 0)) { if(r_y > m_pScroll->verticalScrollBar()->maximum()) { r_y = m_pScroll->verticalScrollBar()->maximum(); } } else { r_y = 0; } if((0 < r_x) | (r_x == 0)) { if(r_x > m_pScroll->horizontalScrollBar()->maximum()) { r_x = m_pScroll->horizontalScrollBar()->maximum(); } } else { r_x = 0; } m_pScroll->verticalScrollBar()->setValue(r_y); m_pScroll->horizontalScrollBar()->setValue(r_x); }
最終實(shí)現(xiàn)效果如下,可以通過(guò)滾輪滾動(dòng)界面,也可以通過(guò)鼠標(biāo)拖拽來(lái)實(shí)現(xiàn)界面拖拽效果:
到此這篇關(guān)于Qt基于QScrollArea實(shí)現(xiàn)界面嵌套移動(dòng)的文章就介紹到這了,更多相關(guān)Qt QScrollArea界面嵌套移動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言代碼實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言代碼實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06opengl實(shí)現(xiàn)任意兩點(diǎn)間畫圓柱體
這篇文章主要為大家詳細(xì)介紹了opengl實(shí)現(xiàn)任意兩點(diǎn)間畫圓柱體,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06C語(yǔ)言中((type *)0) 和(type *0)區(qū)別小結(jié)
((type *)0)?和?(type *0)?在 C 和 C++ 中有不同的含義和用途,本文主要介紹了C語(yǔ)言中((type *)0) 和(type *0)區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08C語(yǔ)言結(jié)構(gòu)體中內(nèi)存對(duì)齊的問(wèn)題理解
內(nèi)存對(duì)齊”應(yīng)該是編譯器的“管轄范圍”。編譯器為程序中的每個(gè)“數(shù)據(jù)單元”安排在適當(dāng)?shù)奈恢蒙?。但是C語(yǔ)言的一個(gè)特點(diǎn)就是太靈活,太強(qiáng)大,它允許你干預(yù)“內(nèi)存對(duì)齊”。如果你想了解更加底層的秘密,“內(nèi)存對(duì)齊”對(duì)你就不應(yīng)該再模糊了2022-02-02C++中的繼承問(wèn)題(繼承基本概念、菱形虛擬繼承的對(duì)象模型)
這篇文章主要介紹了C++中的繼承問(wèn)題(繼承基本概念、菱形虛擬繼承的對(duì)象模型),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02C++實(shí)現(xiàn)LeetCode(648.替換單詞)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(648.替換單詞),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08