QT系列教程(9) 主窗口学习
简介
任何界面应用都有一个主窗口,今天我们谈谈主窗口相关知识。一个主窗口包括菜单栏,工具栏,状态栏,以及中心区域等部分。我们先从菜单栏说起
菜单栏
我们创建一个主窗口应用程序, 在ui文件里的菜单栏里有“在这里输入”的一个菜单,我们双击它输入“文件(&F)”, 这样通过点击alt + F 就可以弹出文件菜单。点击文件菜单,同样会弹出“在这里输入”,我们双击它编辑输入“新建文件(&N)”,可以在右侧的属性栏里为其添加一个图标,同样,我们再添加一个“显示Dock(&D)”的菜单。我们再从左侧的控件Containers里拖动Dock Widget到中心区域,在dock widget中添加一个按钮,一个fontComboBox,一个QTextEdit。DockWidget添加的控件并不会影响主窗口的centralwidget, 我们在centralwidget中添加一个QMdiArea控件。

我们可以选择Action Editor中的两个action,分别为其添加槽函数,右击actionnew_N选择转到槽,然后选择trigger信号,Qt会自动生成槽函数代码

同样的道理为显示dock菜单添加槽函数,然后分别实现两个槽函数
void MainWindow::on_actionnew_N_triggered()
{qDebug() << "新建文件..." << endl;QTextEdit * textEdit = new QTextEdit(this);auto childWindow = ui->mdiArea->addSubWindow(textEdit);childWindow->setWindowTitle(tr("文本编辑子窗口"));childWindow->show();
}void MainWindow::on_actionshowdock_triggered()
{qDebug() << "显示dock widget" << endl;ui->dockWidget_2->show();
}
因为QMdiArea是一个多窗口控件,这样我们每次点击新建菜单就会在窗口的中心部件中创建一个子窗口,多次点击会生成多个子窗口。点击显示dock菜单就会显示dockwidget。
我们可以在代码中添加菜单并创建菜单点击后的回调函数
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QMenu* editMenu = ui->menubar->addMenu(tr("编辑(&E)"));editMenu->addSeparator();QAction * action_Open = editMenu->addAction(QIcon(":/img/head.jpg"), tr("打开文件(&O)"));action_Open->setShortcut(QKeySequence("Ctrl+O"));connect(action_Open,&QAction::triggered, this, &MainWindow::on_action_open_triggered);
}
通过代码我们创建了一个编辑菜单,编辑菜单下有打开文件的动作,设置Ctrl+O为快捷键,并为该动作创建槽函数,然后连结这个槽函数。
void MainWindow::on_action_open_triggered()
{qDebug() << "打开文件..." << endl;
}
所以每次点击打开文件后输出上面的日志。除了可以为菜单栏添加动作外,还可以添加动作组
//建立动作组QActionGroup * group = new QActionGroup(this);QAction * action_L = group->addAction(tr("左对(&L)"));action_L->setCheckable(true);QAction * action_R = group->addAction(tr("右对(&R)"));action_R->setCheckable(true);QAction * action_C = group->addAction(tr("居中(&C)"));action_C->setCheckable(true);editMenu->addSeparator();editMenu->addAction(action_L);editMenu->addAction(action_R);editMenu->addAction(action_C);
我们也可以自定义动作类,我们接下来自定义一个动作类,动作类包含一个label和lineEdit。自定义的动作类叫MyAction,
声明如下
#ifndef MYACTION_H
#define MYACTION_H#include <QWidgetAction>
#include <QLineEdit>
#include <QObject>
class MyAction : public QWidgetAction
{Q_OBJECT
signals:void getText(const QString& string);public:explicit MyAction(QObject * parent = 0);virtual ~MyAction();
protected:virtual QWidget *createWidget(QWidget *parent);private slots:void sentText();
private://声明行编辑器对象QLineEdit* lineEdit;
};#endif // MYACTION_H
createWidget 为一个虚函数,继承自QWidgetAction, 将Action加入菜单或者工具栏就会调用createWidget函数。接下来我们实现这个类
#include "myaction.h"
#include <QSplitter>
#include <QLabel>MyAction::MyAction(QObject * parent):QWidgetAction(parent){// 创建行编辑器lineEdit = new QLineEdit;// 将行编辑器的按下回车键信号和发送文本槽关联connect(lineEdit, &QLineEdit::returnPressed, this, &MyAction::sentText);
}QWidget* MyAction::createWidget(QWidget * parent){if(parent->inherits("QMenu")|| parent->inherits("QToolBar")){QSplitter * spliter = new QSplitter(parent);QLabel * label = new QLabel;label->setText(tr("插入文本:"));spliter->addWidget(label);spliter->addWidget(lineEdit);return spliter;}return 0;
}void MyAction::sentText()
{emit getText(lineEdit->text());lineEdit->clear();
}
构造函数里创建了一个LineEdit,然后绑定了LineEdit的返回信号,在sentText槽函数里发送了getText信号,然后清除了lineEdit里的内容。createWidget里判断了父节点如果是QMenu或者QToolBar,就创建一个spliter,然后将label和lineedit都加入spliter。在mainwindow的构造函数中创建MyAction,并且加入菜单里。然后将MyAction的getText的信号和MainWindow的setText函数绑定在一起。
MyAction * action = new MyAction(this);editMenu->addAction(action);connect(action, &MyAction::getText, this, &MainWindow::setText);
MainWindow的槽函数实现如下
void MainWindow::setText(const QString &string){ui->textEdit->setText(string);
}
这样当我们点击编辑菜单弹出我们自己实现的MyAction动作,在输入框里输入文字按下回车后文字就会显示到dockwidget的textedit中。

工具栏
工具栏相比菜单栏更容易操作,更加直观,添加方式和菜单的方式类似,可以添加label,按钮,以及spinbox等。
可以通过ui添加,也可以通过代码添加,下面用代码添加工具栏菜单。
//工具栏添加元素QToolButton * toolBtn = new QToolButton(this);toolBtn->setText(tr("颜色"));QMenu* colorMenu = new QMenu(this);colorMenu->addAction(tr("红色"));colorMenu->addAction(tr("绿色"));toolBtn->setMenu(colorMenu);toolBtn->setPopupMode(QToolButton::MenuButtonPopup);ui->toolBar->addWidget(toolBtn);QSpinBox* spinBox = new QSpinBox(this);ui->toolBar->addSeparator();ui->toolBar->addWidget(spinBox);
状态栏
状态栏在窗口的下方,一般在右下方,左下方的为临时的,右下方的为永久的。
void MainWindow::init_status_bar(){//显示临时消息ui->statusbar->showMessage(tr("欢迎使用多文档编辑器"),2000);//创建标签QLabel* permanent = new QLabel(this);permanent->setFrameStyle(QFrame::Box | QFrame::Sunken);permanent->setText("llfc.club");ui->statusbar->addPermanentWidget(permanent);
}
总结
源码链接https://gitee.com/secondtonone1/qt-learning-notes
相关文章:
QT系列教程(9) 主窗口学习
简介 任何界面应用都有一个主窗口,今天我们谈谈主窗口相关知识。一个主窗口包括菜单栏,工具栏,状态栏,以及中心区域等部分。我们先从菜单栏说起 菜单栏 我们创建一个主窗口应用程序, 在ui文件里的菜单栏里有“在这里输入”的一个…...
【C++进阶】深入STL之 栈与队列:数据结构探索之旅
📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C “ 登神长阶 ” 🤡往期回顾🤡:模拟实现list与迭代器 🌹🌹期待您的关注 🌹🌹 ❀stack和queue Ǵ…...
SpringBoot发邮件服务如何配置?怎么使用?
SpringBoot发邮件需要的参数?邮件发送性能如何优化? 在SpringBoot项目中配置发邮件服务是一个常见的需求,它允许我们通过应用程序发送通知、验证邮件或其他类型的邮件。AokSend将详细介绍如何在SpringBoot中配置发邮件服务。 SpringBoot发邮…...
AutoCAD Mechanical机械版专业的计算机辅助设计软件安装包下载安装!
AutoCAD机械版作为一款专业的计算机辅助设计软件,不仅具备卓越的二维绘图功能,更是拥有令人瞩目的3D建模工具,为机械设计师们提供了前所未有的创作空间。 在AutoCAD机械版的3D建模环境中,用户可以借助一系列简洁明了的命令&#…...
json.load报错AttributeError: ‘str‘ object has no attribute ‘load‘
with open(json_file, r) as f:data json.load(f)要写个简单的数据处理脚本,报错AttributeError: ‘str’ object has no attribute ‘load’,查看了一下,路径正确,查了半天博客,不知道错在哪里。 回头一看 jsons_pa…...
单词记忆(第二周)
transplant: trans - plant 移植 perceive: per - ceive 察觉 paraphrase: para - ph - rase 释义 prospect: pro - s - pect 前景 access: ac - cess 进入,通道,访问 generous; gene - rous 慷慨的,丰富的 lecture: lec - ture 讲座 …...
RAG:如何从0到1搭建一个RAG应用
通过本文你可以了解到: 什么是RAG?如何搭建一个RAG应用?目前开源的RAG应用有哪些? 大模型学习参考: 1.大模型学习资料整理:大模型学习资料整理:如何从0到1学习大模型,搭建个人或企业…...
leetcode:67二进制求和
题目链接:67. 二进制求和 - 力扣(LeetCode) class Solution { public:string addBinary(string a, string b) {int stralen a.size(), strblen b.size();int curtc;int Maxlen max(stralen, strblen);vector<int> stra;vector<i…...
大模型日报2024-06-10
大模型日报 2024-06-10 大模型资讯 无需矩阵乘法的语言模型在亿参数规模上表现优异 摘要: 研究表明,无需矩阵乘法的语言模型在亿参数规模上仍能保持顶级性能。这一发现挑战了传统神经网络依赖矩阵乘法的观点,展示了在GPU优化之外的新可能性。 博弈论助力…...
【博士每天一篇文献-综述】Modularity in Deep Learning A Survey
阅读时间:2023-12-8 1 介绍 年份:2023 作者:孙浩哲,布朗克斯医疗卫生系统 会议: Science and Information Conference 引用量:4 论文主要探讨了深度学习中的模块化(modularity)概念…...
Sentinel不使用控制台基于注解限流,热点参数限流
目录 一、maven依赖 二、控制台 三、基于注解限流 四、热点参数限流 五、使用JMeter验证 一、maven依赖 需要注意,使用的版本需要和你的SpringBoot版本匹配!! Spring-Cloud直接添加如下依赖即可,baba已经帮你指定好版本了。…...
HTML做成一个端午节炫酷页面
做成端午节页面之前,先了解一下端午节的由来: 1.起源与历史: 端午节起源于中国,始于春秋战国时期,至今已有2000多年历史。 最初是古代百越地区(长江中下游及以南一带)崇拜龙图腾的部族举行图…...
解决Ubuntu系统/usr/lib/xorg/Xorg占用显卡内存问题原创
在Ubuntu系统中,/usr/lib/xorg/Xorg进程占用显卡内存的问题可能会影响系统性能,特别是在使用GPU进行计算任务时。以下是一些解决方法,可以帮助你减少或解决这个问题: 1. 更新显卡驱动 首先,确保你使用的是最新版本的…...
【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现(附源码)(下篇)
作者:后端小肥肠 上篇:【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现(上篇)_spring security activiti7-CSDN博客 目录 1.前言 2. 核心代码 2.1. 流程定义模型管理 2.1.1. 新增流程定义模型数据 …...
解密Spring Boot:深入理解条件装配与条件注解
文章目录 一、条件装配概述1.1 条件装配的基本原理1.2 条件装配的作用 二、常用注解2.1 ConditionalOnClass2.2 ConditionalOnBean2.3 ConditionalOnProperty2.4 ConditionalOnExpression2.5 ConditionalOnMissingBean 三、条件装配的实现原理四、实际案例 一、条件装配概述 1…...
【数据结构与算法】使用数组实现栈:原理、步骤与应用
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 目录 一、引言 🎄栈(Stack)是什么? …...
cell的复用机制和自定义cell
cell的复用机制和自定义cell UITableView 在学习cell之前,我们需要先了解UITableView。UITableView继承于UIScrollView,拥有两个两个相关协议 UITableViewDelegate和UITableViewDataSource,前者用于显示单元格,设置行高以及对单…...
Redis 双写一致原理篇
前言 我们都知道,redis一般的作用是顶在mysql前面做一个"带刀侍卫"的角色,可以缓解mysql的服务压力,但是我们如何保证数据库的数据和redis缓存中的数据的双写一致呢,我们这里先说一遍流程,然后以流程为切入点来谈谈redis和mysql的双写一致性是如何保证的吧 流程 首先…...
《软件定义安全》之四:什么是软件定义安全
第4章 什么是软件定义安全 1.软件定义安全的含义 1.1 软件定义安全的提出 虚拟化、云计算、软件定义架构的出现,对安全体系提出了新的挑战。如果要跟上网络演进的步伐和业务快速创新的速度,安全体系应该朝以下方向演变。 𝟭 安全机制软件…...
将AIRNet集成到yolov8中,实现端到端训练与推理
AIRNet是一个图像修复网络,支持对图像进行去雾、去雨、去噪声的修复。其基于对比的退化编码器(CBDE),将各种退化类型统一到同一嵌入空间;然后,基于退化引导恢复网络(DGRN)将嵌入空间修复为目标图像。可以将AIRNet的输出与yolov8进行端到端集成,实现部署上的简化。 本博…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
