QT多窗口编程与文件IO编程

news/2024/4/27 9:42:18/文章来源:https://blog.csdn.net/m0_68210771/article/details/128437655

目录

一、消息对话框 QMessageBox(掌握)

二、常用窗口类(掌握)

三、主窗口类 QMainWindow(重点)

四、parent参数(掌握)

五、窗口传参

5.1 成员函数/构造函数

5.2 信号槽传参

六、事件机制(掌握)

一、文件选择对话框 QFileDialog(熟悉)

二、文件信息类 QFileInfo

三、文件读写类 QFile(掌握)

四、UI与耗时操作(掌握)

五、多线程 QThread(掌握)

5.1 线程的基本使用

5.2 异步刷新

5.3 关闭线程


一、消息对话框 QMessageBox(掌握)

之前的编程更多的是使用QDebug进行信息的输出,但是QDebug是调试信息,这些信息用户不可见,如果想给用户一些通知信息,使用消息对话框十分合适。

预设了四种消息对话框:

这种预设好的QDialog派生类往往具有一个共同的特点:弹窗使用一个静态成员函数。

如果只是简单弹窗,四种预设窗口的参数是相同的,如下所示:

参数1:依赖的父窗口

参数2:标题

参数3:展示的信息

返回值:枚举,表示用户点击的按键,只对question有意义

二、常用窗口类(掌握)

常用的窗口类继承结构如下所示:

QWidget类除了可以表示所有组件类的基类外,也是所有窗口类的基类,当QWidget构造函数的parent参数没有传递时,表示一个窗口对象;如果传递了,则表示一个组件对象。但是由于QWidget的继承层次比较高,实际开发过程中很少使用它的对象作为窗口和组件。

QWidget的直接派生类不光有对话框窗口类QDialog,还有主窗口类QMainWindow。对于大多软件而言,主窗口只有一个,建议使用QMainWindow,因为QMainWindow包含了菜单栏、工具栏、状态栏等。而QDialog无法胜任功能很多的软件的主窗口。

QWidget类作为所有窗口类的基类,内部也规定了很多窗口类共用的一些函数和属性,例如:

  • 设置窗口标题

void setWindowTitle(const QString &)

通过此函数设置windowTitle属性值,来更改窗口标题文字

  • 设置窗口图标

void setWindowIcon(const QIcon & icon)

通过此函数设置窗口的icon属性,来更改窗口的图标

  • 设置窗口标记

void setWindowFlags(Qt::WindowFlags type)

通过设置窗口标记的枚举值,让窗口达到某种视觉效果。

可以同时设定多个标记,如下所示。

setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint)

  • 设置窗口状态

void QWidget::setWindowState(Qt::WindowStates windowState)

通过设置窗口状态的枚举值,让窗口达到某种显示状态。

三、主窗口类 QMainWindow(重点)

QMainWindow表示主窗口类,因为相比QDialog,它多出了很多部分。本节课程创建的项目主窗口为QMainWindow。

1. 菜单栏 QMenuBar

菜单栏中的每个选项是一个菜单类QMenu对象

,这些对象属于菜单栏。

每个菜单中可以触发的选项被称为“动作”,类名为QAction。每个QAction对象可以通过Designer下方的Action编辑器来设置属性值。

QAction的属性常用属性设定如下:

QAction的常用信号如下:

2. 工具栏 QToolBar

在Designer中,直接把Action编辑器中的QAction拖动到工具栏即可。

3. 中心组件 QWidget

中心组件相当于之前QDialog的内容,用于设计窗口中主要展示的内容。

4. 状态栏 QStatusBar

使用槽函数可以显示或清除状态栏信息。

void QStatusBar::showMessage(const QString & message, int timeout = 0) [slot]

展示信息

参数1:要展示的文字

参数2:显示的时长,参数为毫秒,默认值为持续显示

void QStatusBar::clearMessage() [slot]

清除信息

四、parent参数(掌握)

parent参数除了表示组件与窗口的之间从属关系外,parent参数还能有效地防止内存泄露。所有子组件和子窗口都会等待父窗口销毁时,一并销毁。

下面的例子,自定义一个Qt的窗口类,步骤如下:

1. 在Qt Creator中,选中项目名称,鼠标右键,点击“添加新文件”。

2. 在弹出的窗口中,按照下图所示进行操作。

3. 在弹出的窗口中,配置窗口的相关信息。

4. 在弹出的窗口中,填写类名,点击“下一步”。

5. 在项目管理页面,直接点击完成。可以看到项目中多了一个窗口类的相关文件。

五、窗口传参

5.1 成员函数/构造函数

【例子】有两个窗口(A启动B),在窗口A中转动QDial,窗口B中的另一个QDial跟随转动。

5.2 信号槽传参

【例子】有两个窗口(A启动B),在窗口B中转动QDial,窗口A中的另一个QDial跟随转动。

六、事件机制(掌握)

事件机制是Qt一个核心机制,一些操作可以层层传递,程序员可以在传递的任何一个环节中,捕捉到这个事件并进行处理,不同于信号槽的是,它的使用不需要建立连接。

下图是某事件,从操作系统内核到窗口类的传递过程。

常见的事件对应的处理函数有:

void QWidget::paintEvent(QPaintEvent * event) [virtual protected]

绘制事件函数

void QWidget::resizeEvent(QResizeEvent * event) [virtual protected]

大小改变

void QWidget::mousePressEvent(QMouseEvent * event) [virtual protected]

鼠标按压

void QWidget::mouseReleaseEvent(QMouseEvent * event) [virtual protected]

鼠标释放

void QWidget::mouseDoubleClickEvent(QMouseEvent * event) [virtual protected]

鼠标双击

void QWidget::mouseMoveEvent(QMouseEvent * event) [virtual protected]

鼠标移动

void QWidget::moveEvent(QMoveEvent * event) [virtual protected]

自身移动

void QWidget::keyPressEvent(QKeyEvent * event) [virtual protected]

按键按下

void QWidget::keyReleaseEvent(QKeyEvent * event) [virtual protected]

按键释放

void QWidget::focusInEvent(QFocusEvent * event) [virtual protected]

获取焦点

void QWidget::focusOutEvent(QFocusEvent * event) [virtual protected]

失去焦点

void QWidget::closeEvent(QCloseEvent * event) [virtual protected]

关闭

void QWidget::enterEvent(QEvent * event) [virtual protected]

鼠标进入

void QWidget::leaveEvent(QEvent * event) [virtual protected]

鼠标离开

事件函数的使用步骤如下所示:

1. 查阅文档,确定要使用的事件函数,如:

void QWidget::paintEvent(QPaintEvent * event) [virtual protected]

2. 在头文件中声明事件函数

3. 在源文件中定义(覆盖)事件函数。

4. 在事件函数的函数体中写当前事件触发后执行的逻辑。

一、文件选择对话框 QFileDialog(熟悉)

与QMessageBox一样,QFileDialog也继承自QDialog,表示一个文件读写的选择对话框,这类对话框往往都是通过静态成员函数打开,并且返回值是用户选择的内容。

QFileDialog的常用静态成员函数,如下所示。

函数功能:获取一个读/写的文件路径

参数1:parent参数

参数2:窗口标题

参数3:在哪个路径打开(默认值为工作目录)

参数4:文件类型过滤器

返回值:选中的文件路径,如果用户不选择,则返回“”

二、文件信息类 QFileInfo

获取某一个文件的信息,一个不存在的路径也能创建出对应的QFileInfo对象,但是这样的对象调用exists函数,返回值是false

/**
 * @brief Dialog::printFileInfo 打印文件信息
 * @param path 文件路径
 * @param browser 显示的组件
 */
void Dialog::printFileInfo(QString path, QTextBrowser * browser)
{// 创建文件信息类对象
    QFileInfo info(path);// 获得创建的日期
    QString time = info.created().toString("yyyy-MM-dd hh:mm:ss");
    browser->append(time);if(info.isReadable())
        browser->append("可读");else
        browser->append("不可读");// 获取文件大小
    qint64 size = info.size();
    QString text;
    text.setNum(size).append("字节");
    browser->append(text);
}

三、文件读写QFile(掌握)

QFile类专用于文件的读写,其间接基类是QIODevice,QIODevice类是Qt中所有读写类的基类,内部规定了很多IO的相关基础框架。

QFile类用完即可释放,使用栈内存对象即可,因此也不需要parent参数的传递,构造函数只需要传递文件路径即可。

常用的函数如下:

bool QFile::open(OpenMode mode) [virtual]

以不同的模式打开文件,返回值是打开的结果。

virtual bool atEnd() const

判断是否读取到文件尾

QByteArray QIODevice::read(qint64 maxSize)

读取,参数为最大的字节数,返回值是读取好的字节数组对象

qint64 QIODevice::write(const QByteArray & byteArray)

写出,参数是写出的内容,返回值是实际写出的字节数,出错返回-1

四、UI与耗时操作(掌握)

在默认的情况,Qt只有一个线程,这个线程的主要作用是保证程序的正常执行(事件、信号槽、UI显示、UI交互等),被称为“主线程”或“UI线程”。

但是一些耗时操作(文件读写、网络通信等),如果主线程中执行耗时操作,会导致正常的UI相关操作被阻塞,程序UI出现卡顿、假死的情况。此时如果尝试关闭程序,关闭的命令也会被阻塞,操作系统发现某个程序关闭响应不及时执行,操作系统会弹出来引导用户是否强行关闭。

五、多线程 QThread(掌握)

5.1 线程的基本使用

QThread类是Qt中的线程类,常用函数如下:

void msleep(unsigned long msecs) [static]

让当前线程休眠一定的毫秒数

开启线程的步骤:

1. 在Qt Creator中,选中项目名称,鼠标右键,点击添加新文件。

2. 在弹出的窗口中,按照下图所示进行操作。

3. 依次按照下图所示输入类名、基类名、类型信息后,点击“下一步”。

4. 在项目管理界面,直接点击“完成”。可以看到在项目结构中多了线程类相关的文件。

5. QThread类中有一个void QThread::run() [virtual protected]函数,在自定义线程类中覆盖此函数。

6. 在run函数的函数体中,编写子线程要执行的代码。

7. 在主线程中创建子线程对象后,调用void QThread::start(Priority priority = InheritPriority) [slot]函数启动子线程,此时程序会出现两个执行的线程分支。

5.2 异步刷新

在实际的开发中,经常会遇见以下需求:

在子线程中执行耗时操作,在主线程中执行UI操作,但是主线程的UI操作需要根据子线程的执行情况进行刷新。

此时可以使用信号槽的方式进行线程通信。

需要注意的是,主线程不要执行耗时操作,子线程不要执行UI操作。

5.3 关闭线程

如果一个线程在运行的过程中被强行关闭会出现:

上面的情况说明,线程还咋运行突然被终止。我们应该保证线程先停止。

介绍两种停止线程的方式:

1. terminate

简单粗暴,但是是否即刻停止取决于调度。

2. interrupt

相对温和,内部通过标志位退出。

bool QThread::isInterruptionRequested() const

返回当前线程是否被请求终止。

需要注意的是,线程的run函数执行完也会自动停止。

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

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

相关文章

Android开发进阶——binder通讯学习

什么是binder 通常意义下,binder指的是一种通信机制对Server端来说,Binder指的是Binder本地对象,对于Client端来说,Binder指的是Binder代理对象对于传输过程而言,binder是可以跨进程传输的对象 Binder的基本原理 Bi…

MySQL 管理

文章目录启动及关闭 MySQL 服务器MySQL 用户设置/etc/my.cnf 文件配置管理MySQL的命令启动及关闭 MySQL 服务器 首先,我们需要通过以下命令来检查MySQL服务器是否启动: ps -ef | grep mysqld如果MySql已经启动,以上命令将输出mysql进程列表…

node.js+uni计算机毕设项目基于微信小程序的美甲预约系统(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置: Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等…

Docker安装Zookeeper教程(超详细)

生命无罪,健康万岁,我是laity。 我曾七次鄙视自己的灵魂: 第一次,当它本可进取时,却故作谦卑; 第二次,当它在空虚时,用爱欲来填充; 第三次,在困难和容易之…

【Linux】进程间通信之共享内存

目录🌈前言🌸1、System V共享内存🍡1.1、概念🍢1.2、原理🌺2、共享内存相关函数和指令🍡2.1、shmget函数(创建)🍢2.2、shmctl函数(控制)&#x1f…

【自然语言处理】【ChatGPT系列】ChatGPT的智能来自哪里?

相关博客 【自然语言处理】【ChatGPT系列】ChatGPT的智能来自哪里? 【自然语言处理】【ChatGPT系列】Chain of Thought:从大模型中引导出推理能力 【自然语言处理】【ChatGPT系列】InstructGPT:遵循人类反馈指令来训练语言模型 【自然语言处理…

基于HTML5 技术的开放自动化HMI

人机交互接口(HMI)是自动化系统中不可或缺的一部分。传统的做法是提供一个HMI 显示屏,并且通过组态软件来配置显示屏的功能,通过modbus 或者以太网与PLC 连接。 现在,事情变得复杂了许多,用户不仅需要通过专…

linux共享内存的使用

共享内存可以由多个程序同时访问的内存,能够避免进程间通信过程中的冗余数据拷贝,是IPC中最快的一种,特别适合用来作大块数据的传输。共享内存可以映射到不同的进程空间,这些进程间的数据传递就不再涉及内核。这个过程其实是把同一块物理内存…

FMOC-PEG-COOH,FMOC-PEG-acid,芴甲氧羰基-聚乙二醇-羧基试剂供应

英文名称:FMOC-PEG-COOH,FMOC-PEG-acid 中文名称:芴甲氧羰基-聚乙二醇-羧基 蛋白质、肽和其他材料通过氨基酸或其他酸活性化学组,增加溶解度和稳定性,降低免疫原性;药物修饰或缓释药物研发,新…

ARM_SMMU_下

SMMU驱动代码分析 本文主要分析linux kernel中SMMUv3的代码(drivers/iommu/arm-smmu-v3.c) linux kernel版本是linux 5.7, 体系结构是aarch64 SMMU的作用是把CPU提交给设备的VA地址,直接作为设备发出的地址,变成正确的物理地址,访问到物理内…

[~/vulhub]/log4j/CVE-2021-44228-20221225

[~/vulhub]/log4j/CVE-2021-44228 ┌──(kwkl㉿kwkl)-[~/vulhub] └─$ cd log4j/CVE-2021-44228 ┌──(kwkl㉿kwkl)-[~/vulhub/log4j/CVE-2021-44228] └─$ dir 1.png 2.png docker-compose.yml README.md README.zh-cn.md┌──(kwkl㉿kwkl)-[~/vulhub/log4j/CVE-2021…

_15LeetCode代码随想录算法训练营第十五天-C++二叉树

_15LeetCode代码随想录算法训练营第十五天-C二叉树 题目列表 110.平衡二叉树257.二叉树的所有路径404.左叶子之和 110.平衡二叉树 题目 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每…

SpringBoot-2 读取properties;自动加载127个类原理总结;全部加载,按需配置

读取properties 方式一:非配置类填写:ComponentConfigurationProperties 1)建立bean: /只有在容器中的组件才拥有springboot提供的强大功能 Component ConfigurationProperties(prefix "mycar") public class Car {private Stri…

NetSuite Decode函数

昨天是平安夜,小家伙仍然为圣诞老人的到来准备了礼物,这是他的传统。每年为了感谢圣诞老人和驯鹿的到来,他都会准备上点心、水果。今年,他认为驯鹿可能需要电力,所以准备了电池给它们享用。 真希望天真一直伴随他的成长…

互联网技术不再是统领,当下正在发生着一场深刻的变革

拥抱实体经济,绝对是当下互联网玩家们的首要选择。无论是头部的互联网企业来讲,还是新生的互联网玩家而言,它们都不约而同地将关注的焦点聚焦在了这样一个方向上。   透过这一点,我们可以非常明显地感受到,一个全新的…

蓝桥杯备赛Day4——多维数组

二维数组初始化 p[[0 for i in range(5)] for j in range(2)] #法一 p[[0]*5 for j in range(2)] #法二 s[[1,2,3],[4,5,6]] print(s) for i in range(2):for j in range(3):print(s[i][j],end ) 三维数组初始化 a[[[0 for _ in range(2)] for __ in…

CSDN每日一练最长递增的区间长度 C语言

题目名称:最长递增的区间长度 时间限制:1000ms 内存限制:256M 题目描述 给一个无序数组,求最长递增的区间长度。如:[5,2,3,8,1,9] 最长区间 2,3,8 长度为 3 (注意:测试用例仅做参考,…

windows@网络防火墙@软件联网控制

文章目录ref打开防火墙控制面板常用部分限制某个软件联网文档参考具体操作取消控制/禁用第三方软件控制ref (Windows) 创建出站端口规则 | Microsoft LearnWindows Defender Firewall with Advanced Security (Windows) | Microsoft Learn组策略 Windows) 高级安全性的 Window…

二叉树经典算法题目

1.二叉树的前中后序遍历(简单) 省略 2.二叉树的深度(简单) 输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。 例如&a…

VS coda C++、python运行与Dbug配置

首先新建终端 一次性使用C方法 检查C编译器是否存在 which g可见位置存在于:/usr/bin/g 一次性命令格式: 使用json配置文件 运行C方法(推荐): 根据你查找的g的位置来决定 使用配置好的tasks.json(C的…