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

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

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


- 源码实现如下
patchwindow.h

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
patchwindow.cpp

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 }
mainwindow.h

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
mainwindow.cpp

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 }
- 最终实现效果如下,可以通过滚轮滚动界面,也可以通过鼠标拖拽来实现界面拖拽效果:

工程源码下载路径:
「ScrollArea」https://www.aliyundrive.com/s/QMf912nt86A 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
QT 基于QScrollArea的界面嵌套移动的更多相关文章
- 基于qml创建最简单的图像处理程序(1)-基于qml创建界面
<基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...
- Qt基于tcp协议网络编程
基于Qt网络编程: 基于tcp协议 c/s模式编程 所需要的类:QTcpServer QTcpSocket 利用qt基于tcp协议编写c/s模式程序: 两个类中的信号: QTcpServer : ne ...
- qml(Qt Quick)做界面
qml(Qt Quick)做界面 来源 https://www.zhihu.com/question/24880681/answer/29324824 本人是Qt初学者,正在写一个会计小软件(Lin ...
- Qt常用的登录界面设计
记录一下Qt常用的登录界面的设计 方便以后使用! 1.QpushButton改变一个按钮的颜色,当鼠标放上去和移开时显示不同的颜色.QPushButton { background-color: rg ...
- 第15.10节 PyQt(Python+Qt)入门学习:Qt Designer可视化设计界面组件与QWidget类相关的组件属性详解
PyQt学习有阵子了,对章节的骨架基本考虑好了,准备本节就写组件的属性的,结果一是日常工作繁忙,经常晚上还要加班,二是Qt的组件属性很多,只能逐一学习.研究和整理,花的时间有点长,不过终于将可视化设计 ...
- 基于JavaFX图形界面演示的迷宫创建与路径寻找
事情的起因是收到了一位网友的请求,他的java课设需要设计实现迷宫相关的程序--如标题概括. 我这边不方便透露相关信息,就只把任务要求写出来. 演示视频指路: 视频过审后就更新链接 完整代码链接: 网 ...
- QT基于model/view数据库编程2
Qt中数据编程主要分为以下两点:1.利用qt提供类 访问数据库或者成为简单的数据库编程2.数据库编程中引入model/view编程模型 基于model/view数据库编程: qt提供model类: Q ...
- 第九章、Qt Designer可视化设计界面布局组件介绍
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 在Qt Designer中,在左边部件栏的提供了界面布局相关部件,如图: 可以看到共包含有 ...
- window.parent != window 解决界面嵌套问题
页面在被嵌套的时,效果:,,如果用户点击“刷新”,该问题即可解决. 如果想通过代码解决的话,这个问题属于客户端的问题,不是服务器端的问题. 如果直接写:window.location.href = “ ...
随机推荐
- 浅谈arguments属性callee
1.首先 arguments 是一个对应于传递给函数的参数的类数组对象 2. arguments.callee 属性包含当前正在执行的函数. 描述 callee 是 arguments 对象的一个属性 ...
- 前端框架小实验-在umi框架中以worker线程方式使用SQL.js的wasm
总述:在Win7环境下配置umijs框架,在框架中用worker线程方式使用SQL.js的wasm,在浏览器端实现数据的增删改查以及数据库导出导入. 一.安装node.js 1.Win7系统只支持no ...
- 序列化器中钩子函数源码分析、many关键字源码分析
局部钩子和全局钩子源码分析(2星) # 入口是 ser.is_valid(),是BaseSerializer的方法 # 最核心的代码 self._validated_data = self.run_v ...
- node.js - 包、express
首先,要先在这里分享一下我的喜悦,从昨天开始其实一直都在喜悦当中的,我收到了我的第一份offer,这感觉不摆了,比第一桶金都还舒服,虽然我还没收到第一桶金哈哈,不过offer都得了应该也快了. 今天的 ...
- 代码源 BFS练习1
BFS练习1 http://oj.daimayuan.top/course/11/problem/147 题目 思路 四个方向进行BFS 注意:此题读写量大,cin会被卡 代码 #include &l ...
- 深度剖析text-align家族
大家好,我是半夏,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注 点赞 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师-关注公众号:搞前端的半夏,了解更多前端知 ...
- 面渣逆袭:Spring三十五问,四万字+五十图详解
大家好,我是老三啊,面渣逆袭 继续,这节我们来搞定另一个面试必问知识点--Spring. 有人说,"Java程序员都是Spring程序员",老三不太赞成这个观点,但是这也可以看出S ...
- .NET宝藏API之:IHostedService,后台任务执行
我们在项目开发的过程中可能会遇到类似后台定时任务的需求,比如消息队列的消费者. 按照.NetF时的开发习惯首先想到的肯定是Windows Service,拜托,都什么年代了还用Windows服务(小声 ...
- python学习-Day24
目录 今日内容详细 主菜 : ATM+购物车作业 项目开发流程 需求分析 架构设计 分组开发 项目测试 交付上线 需求分析 提炼项目功能 项目大致技术栈 架构设计 编程历经过程 三层架构 将ATM分为 ...
- 借助ADB冻结与卸载Android系统应用(免ROOT)
背景: 我妈的手机饱受系统应用广告推送之苦,每天都能在通知栏里收到好几条广告.为了给她个清净,本篇博文应运而生. 目标: 卸载安卓系统应用 所用工具: 硬件:我妈的手机(魅蓝5) PC端:Minima ...