【Qt】窗口

文章目录

  • QMainWindow
  • 菜单栏
  • 工具栏
  • 状态栏
  • 浮动窗口
  • 对话框
    • 自定义对话框
    • Qt内置对话框
      • QMessageBox


QMainWindow

Qt中的主窗口以QMainWindow表示,其总体结构如下:

image-20240717180426433

菜单栏

菜单栏MenuBar,可包含多个菜单Menu,每个菜单也可以包含多个菜单项Action,以QtCreator的菜单栏为例。

image-20240715165003274

Qt中,QMenuBar表示菜单栏,QMenu表示菜单,QAction表示菜单项。

核心接口

接口说明
void QMainWindow::setMenuBar(QMenuBar *menuBar)为主窗口设置菜单栏
addMenu(QMenu *menu)为菜单栏添加菜单,或在菜单中嵌套添加子菜单
QWidget::addAction(QAction *action)
QMenu::addAction(const QString &text)
添加菜单项,可以使用QAction添加,也可直接以文本添加

先上代码。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1.创建一个菜单栏,并将其设置到窗口MainWindow中QMenuBar* menuBar = this->menuBar();this->setMenuBar(menuBar);//2.为菜单栏创建菜单QMenu* menu1 = new QMenu("文件 (&F)");QMenu* menu2 = new QMenu("编辑 (&E)");QMenu* menu3 = new QMenu("帮助 (&H)");//3.将菜单加入菜单栏中menuBar->addMenu(menu1);menuBar->addMenu(menu2);menuBar->addMenu(menu3);//(嵌套子菜单)QMenu* menu31 = new QMenu("目录");menu3->addMenu(menu31);menu31->addAction("h1");//直接使用字符串也可以添加菜单项menu31->addAction("h2");menu31->addAction("h3");//4.为菜单创建一些菜单项ActionQAction* action1 = new QAction("新建 (&N)");QAction* action2 = new QAction("打开 (&O)");QAction* action3 = new QAction("另存为 (&S)");menu1->addAction(action1);menu1->addSeparator();//在菜单项之间增加分隔线menu1->addAction(action2);menu1->addSeparator();menu1->addAction(action3);//(为菜单项设置图标)action1->setIcon(QIcon(":/create.png"));action2->setIcon(QIcon(":/open.png"));action3->setIcon(QIcon(":/save.png"));//5.为Aciton的触发绑定槽函数connect(action1, &QAction::triggered, this, &MainWindow::handle1);connect(action2, &QAction::triggered, this, &MainWindow::handle2);connect(action3, &QAction::triggered, this, &MainWindow::handle3);//6.为菜单栏添加一个用于关闭窗口的ActionQAction* action = new QAction("关闭 (&C)");menuBar->addAction(action);connect(action, &QAction::triggered, this, &MainWindow::close);
}
  1. 创建菜单栏时,可以使用以下两种方式:

    //1.
    QMenuBar* menuBar = new QMenuBar();
    this->setMenuBar(menuBar);
    //2.
    QMenuBar* menuBar = this->menuBar();
    this->setMenuBar(menuBar);
    

    第一种方法是直接创建QMenuBar对象,然后通过setMenuBar()设置菜单栏,这种方法可能会导致内存泄露,因为有时候菜单栏是已经存在的!比如ui文件会自动生成菜单栏,此时如果手动创建一个并set为菜单栏,就会覆盖原先的菜单栏,导致其内存泄漏。

    正确的方法是调用QMainWindow的接口menuBar(),其功能:若菜单栏已存在,则返回已存在的菜单栏,若不存在,则创建一个新的菜单栏再返回。

  2. 创建菜单时,需要为菜单设置一个文本title,而你可以在title中使用&指定该菜单的快捷键,如:QMenu* menu1 = new QMenu("文件 (&F)"),则F为该菜单的快捷键,ALT + F触发该菜单。同理,创建QAction菜单项时也可用同样的方法设置菜单项的快捷键。

  3. 菜单可以嵌套,即为QMenu添加另外一个QMenu

  4. addSeparator()在菜单项之间添加分隔线,优化界面。还可以为菜单项添加图标icon。

  5. 菜单模块中,最后与用户交互的是QAction。用户点击某个菜单项,触发QActiontriggered信号,通过信号槽机制定义处理方法。需要注意的是,不仅菜单栏可以添加QAction,菜单也可以添加QActionQAction抽象出公共的用户交互动作。

最终效果:

image-20240715172051348 image-20240715172100394

工具栏

⼯具栏是应用程序中集成各种功能,实现快捷使⽤的⼀个区域。可有可无,不是程序中必须存在的部件。在Qt中QToolBar表示工具栏,是一个可移动的组件,QAction表示工具栏中的快捷项。一个窗口可以有多个工具栏。

先上代码。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1.创建工具栏QToolBar* toolBar = new QToolBar();this->addToolBar(toolBar);//一个窗口可以有多个工具栏, 因此使用add而非set//2.添加快捷项QAction* action1 = new QAction("保存");QAction* action2 = new QAction("打开");toolBar->addAction(action1);toolBar->addAction(action2);//设置快捷项图标action1->setIcon(QIcon(":/save.png"));action2->setIcon(QIcon(":/open.png"));//设置快捷项的提示信息action1->setToolTip("点击此处保存文件");action2->setToolTip("点击此处打开文件");//绑定触发快捷项的槽函数connect(action1, &QAction::triggered, this, [](){qDebug() << "保存成功";});connect(action2, &QAction::triggered, this, [](){qDebug() << "打开成功";});
}

image-20240716101336321

关于工具栏的停靠位置,可以在添加QToolBar对象时指定,停靠位置由枚举类型Qt::ToolBarArea提供,有四种.

enum ToolBarArea {LeftToolBarArea = 0x1,//左RightToolBarArea = 0x2,//右TopToolBarArea = 0x4,//上BottomToolBarArea = 0x8//下
};//为窗口添加工具栏时,指定工具栏的初始停靠位置
QToolBar* toolBar = new QToolBar();
this->addToolBar(Qt::LeftToolBarArea, toolBar);

后续可以通过代码,决定工具栏允许停靠的位置、是否允许浮动、是否允许移动。

//3.工具栏的位置
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);//设置允许停靠的位置
toolBar->setFloatable(false);//设置是否可以浮动 (默认为true)
toolBar->setMovable(true);//设置是否可以移动 (默认为true)

同一个QAction可以为菜单项和工具栏中的快捷项共享,快捷项成为菜单项的快捷方式。在上述代码作出以下修改。

//创建菜单栏
QMenuBar* menuBar = this->menuBar();
this->setMenuBar(menuBar);
QMenu* menu = new QMenu("文件");
menuBar->addMenu(menu);
//...
//添加action1菜单项(action1已添加为工具栏的快捷项)
menu->addAction(action1);

状态栏

状态栏是应⽤程序中输出简要信息的区域。⼀般位于主窗口的最底部,⼀个窗口中最多只能有⼀个状态栏。在Qt中,状态栏是通过QStatusBar类来实现的。在状态栏中可以显示的消息类型有:

• 实时消息:如当前程序状态
• 永久消息:如程序版本号,机构名称
• 进度消息:如进度条提示

我们可以调用状态栏的showMessage()函数输出一些简单的临时信息,也可以在状态栏中添加一些控件widget,以显示特定的信息。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1.创建状态栏QStatusBar* statusBar = this->statusBar();//存在则直接获取,不存在则先创建this->setStatusBar(statusBar);//2.显示信息statusBar->showMessage("This is statusBar!!");//也可以为显示信息添加timeout超时时间,单位为ms
}

为状态栏添加一些控件

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1.创建状态栏QStatusBar* statusBar = this->statusBar();//存在则直接获取,不存在则先创建this->setStatusBar(statusBar);//2.创建控件QLabel* label = new QLabel("This is a statusBar!!");QProgressBar* progressBar = new QProgressBar();progressBar->setValue(50);//3.添加控件到状态栏中,可以为控件设置拉伸系数statusBar->addWidget(label, 1);//从左往右添加statusBar->addPermanentWidget(progressBar, 2);//从右往左添加
}
image-20240716105224810

浮动窗口

在Qt中,浮动窗口也称之为铆接部件,一般作为主窗口内部的子窗口。浮动窗口是通过QDockWidget类来实现浮动的功能。浮动窗口⼀般是位于核心部件的周围,可以有多个。

注意,Qt中规定QDockWidget中只能有一个QWidget,因此若需要在浮动窗口中实现更多效果,需要先创建一个QWidget,对QWidget进行创造,再将其设置到浮动窗口QDockWidget中。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1.创建浮动窗口QDockWidget* dockWidget = new QDockWidget();this->addDockWidget(Qt::LeftDockWidgetArea, dockWidget);//注意,添加浮动窗口时须指定其停靠位置(上下左右)//2.为浮动窗口设置一个QWidgetQWidget* widget = new QWidget();dockWidget->setWidget(widget);//3.在widget中添加一些控件QVBoxLayout* layout = new QVBoxLayout();widget->setLayout(layout);QLabel* label = new QLabel("This is a dockWidget!!");QPushButton* btn1 = new QPushButton("按钮1");QPushButton* btn2 = new QPushButton("按钮2");layout->addWidget(label);layout->addWidget(btn1);layout->addWidget(btn2);//4.设置浮动窗口只能停靠左侧或右侧dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
}
image-20240716110637317

对话框

对话框通常是⼀个顶层窗⼝,出现在程序最上层,⽤于实现短期任务或者简洁的用户交互。Qt的对话框由类QDialog实现。Qt中还提供了一些内置对话框,方便特殊场景下的开发,Qt常用的内置对话框有:QFiledialog(⽂件对话框)、QColorDialog(颜⾊对话框)、QFontDialog(字体对话框)、QInputDialog(输⼊对话框)和 QMessageBox(消息框)。

//主窗口设置一个按钮,点击按钮弹出对话框
void MainWindow::on_pushButton_clicked()
{//1.创建对话框QDialog* dialog = new QDialog(this); dialog->resize(500,300);dialog->setWindowTitle("对话框");//2.显示对话框dialog->show();
}
  • 关于对话框的内存泄漏问题

    上述创建对话框的过程,虽然将对话框的父节点设置为上级主窗口,但是防不住用户在主窗口销毁之前,打开的对话框过多、或对话框占用内存过大,导致内存泄漏。我们想要达成的效果是:用户关闭一个对话框(点击对话框左上角的❌)时,就将该对话框delete。Qt中为对话框QDialog内置了一些属性,设置WA_DeleteOnClose属性表示对话框关闭时释放内存。

    dialog->setAttribute(Qt::WA_DeleteOnClose);
    
  • 对话框有两种类型,模态(modal) 和 非模态。

    模态对话框:显示后无法与父窗口进行交互,是⼀种阻塞式的对话框。使用QDialog::exec()函数调用。模态对话框适用于一些必须让用户作出选择的场景,如:文件选择、打印设置等。

    非模态对话框:显示后依然可以与父窗口进行交互,是一种非阻塞式的对话框。使用QDialog::show()函数调用。

自定义对话框

  1. Qt提供对话框基类QDialog,开发者如果需要自定义一个对话框,就需要以QDialog为父类,创建一个派生类,在派生类中自定义一些控件、GUI效果等。具体做法,可以通过QtCreator内的文件菜单,创建一个继承自QDialog的派生类,并在自动生成的头文件和源文件中,自定义派生类。
//这里创建了一个Dialog类,继承自QDialog
//在其构造函数中,添加一些控件
Dialog::Dialog(QWidget* parent) : QDialog(parent)
{QVBoxLayout* layout = new QVBoxLayout();this->setLayout(layout);QLabel* label = new QLabel("This is a Dialog!!");QPushButton* btn = new QPushButton("按钮");layout->addWidget(label);layout->addWidget(btn);
}
image-20240716171035809
  1. 通过创建对话框的ui文件,进行图形化的自定义。

Qt内置对话框

QMessageBox

QMessageBOX是消息对话框,主要用于为用户提示主要的信息,或是让用户进行选择操作。

一个消息对话框中的内容,主要包括:标题、提示信息、消息类型(图标)和按钮。

先上代码。

void MainWindow::on_pushButton_clicked()
{QMessageBox* msgBox = new QMessageBox(this);msgBox->setWindowTitle("消息对话框");//设置标题msgBox->setText("Warning");//设置提示信息msgBox->setIcon(QMessageBox::Warning);//设置消息的类型msgBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);//设置标准按钮// 也可以调用addButton为消息对话框添加自定义按钮,但是一般用标准按钮就足够了// msgBox->addButton()
}

image-20240716172202071

消息类型

enum Icon {NoIcon = 0,Information = 1,Warning = 2,Critical = 3,Question = 4
};
类型适用场景
Question用于正常操作过程中的提问
Information用于提示正常运行的消息
Warning用于提示非关键的错误(警告)
Critical用于提示严重错误

事实上,QMessageBox提供了一系列静态函数,用于创建一个消息对话框,一个函数涵盖了设置标题、文本、消息类型和按钮等功能。如下,四个不同的静态函数,表示创建四种不同类型的消息对话框。

image-20240716173408202

void MainWindow::on_pushButton_clicked()
{QMessageBox::warning(this,"消息对话框","Do you want to do something?", QMessageBox::Ok | QMessageBox::No);
}
image-20240716173755704

使用静态函数生成的对话框是模态类型的。

  • 如何获取用户与消息对话框交互的结果?

    对于模态类型的消息对话框,其exec()返回值就是用户选择的结果!返回的是选择的StandardButton的值。(Qt::StandardButton是一个枚举类型,每一种按钮对应一个特定值)。而criticalinformation, warning, question四个静态函数的返回值是QMessageBox::StandardButton,就是返回用户点击的按钮。

    我们可以根据这个返回值,对用户不同的选中作出不同的处理。

    void MainWindow::on_pushButton_clicked()
    {int ret = QMessageBox::warning(this,"消息对话框","Do you want to do something?", QMessageBox::Ok | QMessageBox::No);if(ret == QMessageBox::Ok){qDebug() << "Ok, lets do it";}else if(ret == QMessageBox::No){qDebug() << "Alright, Bye";}
    }
    

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

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

相关文章

Godot游戏制作 03世界构建1.0版

在game场景&#xff0c;删除StaticBody2D节点&#xff0c;添加TileMap节点 添加TileSet图块集 添加TileSet源 拖动图片到图块&#xff0c;自动创建图块 使用橡皮擦擦除。取消橡皮擦后按住Shift创建大型图块。 进入选择模式&#xff0c;TileMap选择绘制&#xff0c;选中图块后在…

Java——————接口(interface) <详解>

1.1 接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本电脑上的USB接口&#xff0c;电源插座等。 电脑的USB口上&#xff0c;可以插&#xff1a;U盘、鼠标、键盘...所有符合USB协议的设备 电源插座插孔上&#xff0c;可以插&#xff…

若依Vue前后端分离版如何部署(windows)(超详细)

一、项目环境准备 下面是项目所需要准备的环境 Node.js redis 1、Node.js下载 下面进入官网可以下载Node.js — 在任何地方运行 JavaScript (nodejs.org)https://nodejs.org/zh-cn 下载完成安装后&#xff0c;需要配置环境变量&#xff0c;首先复制以下nodejs的安…

springboot系列十一:Thymeleaf

文章目录 官方文档基本介绍Thymeleaf机制说明Thymeleaf语法表达式运算符th属性迭代条件运算使用Thymeleaf th属性需要注意点 Thymeleaf综合案例需求说明思路分析代码实现 作业布置 官方文档 在线文档: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html 离线…

css黑色二级下拉导航菜单

黑色二级下拉导航菜单https://www.bootstrapmb.com/item/14816 body { font-family: Arial, sans-serif; margin: 0; padding: 0; }nav { background-color: #000; /* 导航背景色为黑色 */ }.menu { list-style-type: none; margin: 0; padding: 0; overflow: hidden; }.menu l…

ARP欺骗——华为ensp

首先&#xff0c;搭建好网络拓扑。网络设备包含客户端Client1和服务端Server1&#xff0c;交换机 以及 云。 图中的 Client和Server 配置IP地址&#xff0c;要和 vm8 在相同的网段。故设置客户端ip为192.168.11.10 &#xff0c;服务端ip为&#xff1a;192.168.11.20&#xff0…

uni-app AppStore Connect上传拒绝汇总

1.Guideline 2.3.3 - Performance - Accurate Metadata 问题是图片不对&#xff0c;最好是自己截图&#xff0c;然后用香蕉云编 上传图片合成图片 2.Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing 解决办法&#xff1a;在uniapp manifest.json找到 APP常用其他…

【Ubuntu】Ubuntu系统镜像

清华镜像源 Index of /ubuntu-releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source MirrorIndex of /ubuntu-releases/ | 清华大学开源软件镜像站&#xff0c;致力于为国内和校内用户提供高质量的开源软件镜像、Linux 镜像源服务&#xff0c;帮助用户更方便地获取开源软…

Llama 3.1要来啦?!测试性能战胜GPT-4o

哎呀&#xff0c;Meta声称将于今晚发布的Llama 3.1&#xff0c;数小时前就在Hugging Face上泄露出来了&#xff1f;泄露的人很有可能是Meta员工&#xff1f; 还是先来看泄露出来的llama3.1吧。新的Llama 3.1模型包括8B、70B、405B三个版本。 而经过网友测试&#xff0c;该base…

Langchain核心模块与实战[8]:RAG检索增强生成[loader机制、文本切割方法、长文本信息处理技巧]

Langchain核心模块与实战[8]:RAG(Retrieval Augmented Generation,检索增强生成) RAG(Retrieval-Augmented Generation)技术是一种结合检索和生成功能的自然语言处理(NLP)技术。该技术通过从大型外部数据库中检索与输入问题相关的信息,来辅助生成模型回答问题。其核心…

gitee的怎么上传项目

前提 1.先下载Git Bash (如果没有下载的宝子们下载连接如下: 链接: link ) 项目上传到Gitee步骤 1.在Gitee上建立远程仓库 2.填写相关信息 3.进入本地你想要上传的文件目录下&#xff0c;右键单击空白处&#xff0c;点击Git Bash Here 4.配置你的用户名和邮箱 git con…

使用Ollama和OpenWebUI,轻松探索Meta Llama3–8B

大家好&#xff0c;2024年4月&#xff0c;Meta公司开源了Llama 3 AI模型&#xff0c;迅速在AI社区引起轰动。紧接着&#xff0c;Ollama工具宣布支持Llama 3&#xff0c;为本地部署大型模型提供了极大的便利。 本文将介绍如何利用Ollama工具&#xff0c;实现Llama 3–8B模型的本…

Android APP CameraX应用(02)预览流程

说明&#xff1a;camera子系统 系列文章针对Android12.0系统&#xff0c;主要针对 camerax API框架进行解读。 1 CameraX简介 1.1 CameraX 预览流程简要解读 CameraX 是 Android 上的一个 Jetpack 支持库&#xff0c;它提供了一套统一的 API 来处理相机功能&#xff0c;无论 …

爬虫学习3:爬虫的深度爬取

爬虫的深度爬取和爬取视频的方式 深度爬取豆瓣读书 import time import fake_useragent import requests from lxml import etree head {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 …

双向链表(C语言版)

1. 双向链表的结构 注意&#xff1a;这里的“带头”跟单链表的“头结点”是两个概念&#xff0c;实际上在单链表阶段称呼不太严谨&#xff0c;但是为了更好地理解就直接称为单链表的头结点。带头链表里的头结点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位结点不存储任何有…

MaxSite CMS v180 文件上传漏洞(CVE-2022-25411)

前言 CVE-2022-25411 是一个影响 Maxsite CMS v180 的远程代码执行漏洞。攻击者可以通过上传一个特制的 PHP 文件来利用这个漏洞&#xff0c;从而在受影响的系统上执行任意代码。 漏洞描述 该漏洞存在于 Maxsite CMS v180 的文件上传功能中。漏洞利用主要通过允许上传带有危…

Vue 3项目安装Element-Plus

Element Plus 是一个基于 Vue 3 的现代前端UI框架&#xff0c;它旨在提升开发体验&#xff0c;并为开发者提供高效、优雅的组件。如果你正在使用 Vue 3 进行项目开发&#xff0c;那么安装和集成 Element Plus 是一个不错的选择。在本文中&#xff0c;博主将详细介绍如何在 Vue …

【SASS/SCSS(三)】样式的复用与动态计算(@mixin和@function)

目录 一、mixin 1、定义复用的样式代码&#xff0c;接受传参&#xff0c;搭配include使用。 位置传参 关键词传参 ...语法糖接受传入的任意参数 2、在mixin中使用content&#xff0c;获取外部对mixin的追加内容 二、function 三、字符串——值得注意的点 很多时候&#…

智慧大棚数据库版

创建一个SMartBigHouse数据库 在数据库创建一个表用来存储数据 这边将id设为主键并将标识增量设为1 搭建Winfrom 搭建历史查询界面 串口数据&#xff0c;(这边是用的一个虚拟的串口工具&#xff0c;需要的话私) ModbusSerialMaster master;DataPointCollection wenduValues; //…

细说MCU用DMA控制ADC采样和串口传送的实现方法

目录 一、建立工程 1.相同的配置 2.配置ADC 3.配置DMA 二、代码修改 1.定义存储ADC采样结果的数组 2.启动ADC与定时器 3.编写主程序代码 4.重定义回调函数 5.查看结果 三、修改DMA模式 1. 修改DMA模式为Circular 2.查看结果 采用DMA(Direct Memory Access&#xf…