当前位置: 首页 > news >正文

Qt——窗口

目录

认识

菜单栏

工具栏

状态栏

QDockWidget

对话框

模态与非模态

QMessageBox

QColorDialog

QFileDialog

QFontDialog

QInputDialog


认识

        Qt 窗⼝ 是通过 QMainWindow 来实现的:

  • QMainWindow 是⼀个为用户提供主窗⼝程序的类,继承⾃ QWidget 类,并且提供了⼀个预定义的布局
  • QMainWindow 包含 ⼀个菜单栏(menu bar)、多个⼯具栏(tool bars)、多个浮动窗⼝(dock widgets)、⼀个状态栏(status bar) 和⼀个中心部件(central widget)

        如下图为 QMainwindow 中 各组件所处的位置

菜单栏

        Qt 中的菜单栏是通过 QMenuBar 这个类来实现的。⼀个主窗⼝最多只有⼀个菜单栏。位于主窗⼝顶部、主窗⼝标题栏下⾯;菜单栏中包含菜单,菜单中包含菜单项

        为什么菜单项不命名成 QMenuItem 呢?        主要是要与工具栏进行兼容:工具栏本质上也是菜单栏的“快捷方式”:点击菜单项是一次动作,点击工具栏上的选项也是一次动作,Qt 使用 QAction 就是把这二者进行了统一

        创建 Qt项目进行使用,此时选择的就不是 QWidget,则是 QMainWinodw

        ui 上进行添加

        设置后运行,查看运行结果

        使用代码进行实现

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建菜单栏QMenuBar* bar = new QMenuBar(this);// 创建菜单QMenu* menu1 = new QMenu("文件");QMenu* menu2 = new QMenu("视图");bar->addMenu(menu1);bar->addMenu(menu2);// 创建菜单栏QAction* action1 = new QAction("新建");QAction* action2 = new QAction("保存");QAction* action3 = new QAction("另存为");menu1->addAction(action1);menu1->addAction(action2);menu1->addAction(action3);// 关联信号connect(action1,&QAction::triggered,this,&MainWindow::hadnler);
}

  • 给菜单和菜单项设置快捷键
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建菜单栏QMenuBar* bar = new QMenuBar();this->setMenuBar(bar);// 创建菜单QMenu* menu1 = new QMenu("文件 (&F)");QMenu* menu2 = new QMenu("视图 (&V)");bar->addMenu(menu1);bar->addMenu(menu2);// 创建菜单栏QAction* action1 = new QAction("新建 (&C)");QAction* action2 = new QAction("保存 (&S)");QAction* action3 = new QAction("另存为 (&A)");QAction* action4 = new QAction("打开 (&O)");menu1->addAction(action1);menu1->addAction(action2);menu1->addAction(action3);menu2->addAction(action4);// 关联信号connect(action1,&QAction::triggered,this,&MainWindow::hadnler);
}

  • 菜单除了可以添加菜单项,还可以添加子菜单,子菜单中再添加菜单项(嵌套菜单)
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建菜单栏QMenuBar* bar = new QMenuBar();this->setMenuBar(bar);// 创建菜单QMenu* Parent = new QMenu("菜单");QMenu* Child = new QMenu("子菜单");bar->addMenu(Parent);Parent->addMenu(Child);// 创建菜单项QAction* action = new QAction("菜单项");Child->addAction(action);
}

  • 菜单项添加分割线
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建菜单栏QMenuBar* bar = new QMenuBar();this->setMenuBar(bar);QMenu* menu = new QMenu("菜单");bar->addMenu(menu);// 创建菜单项QAction* action1 = new QAction("菜单项1");QAction* action2 = new QAction("菜单项2");menu->addAction(action1);// 添加分割线menu->addSeparator();menu->addAction(action2);
}

  • 添加图标

        使用前面的 QIcon 和 qrc 机制来完成

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建菜单栏QMenuBar* bar = new QMenuBar();this->setMenuBar(bar);// 创建菜单QMenu* menu = new QMenu("菜单");menu->setIcon(QIcon(":/1.png"));bar->addMenu(menu);// 创建子菜单QMenu* menu_child = new QMenu("子菜单");menu_child->setIcon(QIcon(":/1.png"));menu->addMenu(menu_child);// 创建菜单项QAction* action = new QAction("菜单项");action->setIcon(QIcon(":/1.png"));menu_child->addAction(action);
}

        菜单栏中的菜单添加图标后不显示文本,而子菜单和菜单项都显示了,原始是 Qt 考虑到菜单栏可能有很多,内容放不下,添加图标后把文本给覆盖了

        上面创建项目中我们勾选了自动生成 ui 文件

        所以会给我们自动生成一个菜单栏

        如果按照之前的代码,就会把 menubar 进行替换,同时把它从对象树上移除,所以每次启动关闭窗口就有内存泄漏,所以要想优雅地,正确写出代码来,用它自动生成的反而更好

工具栏

        工具栏就没有自动创建一说了,所以说需要自己创建了

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QToolBar* tool = new QToolBar();this->addToolBar(tool);// 设置图标后文件就以提示词呈现QAction* action1 = new QAction("工具栏1");QAction* action2 = new QAction("工具类2");// 也可以自行设置提示词action1->setToolTip("这是一个提示词");// 一般工具栏是以图标展示action1->setIcon(QIcon(":/1.png"));action2->setIcon(QIcon(":/1.png"));tool->addAction(action1);tool->addAction(action2);// 工具栏的内容一般在菜单栏存在QMenuBar* menu_bar = ui->menubar;QMenu * menu = new QMenu("菜单");menu_bar->addMenu(menu);menu->addAction(action1);menu->addAction(action2);
}

             

        一个 Action 的父节点既是 QToolBar 也是 QMenu,对象树释放时会不会释放两次?        Qt考虑到这方面的问题,所有会跟随最近是否的父节点一同释放,之后就不会释放了

  • 工具栏的位置
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QToolBar* tool1 = new QToolBar();QToolBar* tool2 = new QToolBar();// 添加工具类可以拖动到左右两测tool2->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);// 添加工具栏this->addToolBar(tool1);// 添加工具栏的起始位置this->addToolBar(Qt::LeftToolBarArea,tool2);QAction* action1 = new QAction("工具1");QAction* action2 = new QAction("工具2");tool1->addAction(action1);tool2->addAction(action2);
}

状态栏

        一般在窗口最下方,使用 QStatusBar 实现,一般提示

  • 实时消息:如当前程序状态
  • 永久消息:如程序版本号,机构名称
  • 进度消息:如进度条提⽰,百分百提示
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 有创建返回,没有创建则会新创建QStatusBar* status = this->statusBar();// 如果有创建该代码不起效果this->setStatusBar(status);// 设置的时间内显示提示信息//status->showMessage("hello qt",3000);QLabel * label1 = new QLabel("这是 label1 提示词");status->addWidget(label1);QLabel * label2 = new QLabel("这是 label2 提示词");status->addPermanentWidget(label2);
}

QDockWidget

        创建浮动窗口,也就是在主窗口中创建子窗口

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QDockWidget* dock = new QDockWidget();// 添加的同时需要设置浮动窗口的位置this->addDockWidget(Qt::RightDockWidgetArea,dock);dock->setWindowTitle("这是一个 dock 窗口");// dock 只能添加一个 QWidget,所以先创建一个 QWidget 容器QWidget* contain = new QWidget();// 再创建一个布局管理器QVBoxLayout* layout = new QVBoxLayout();// 往 layout 添加组件QLabel* label = new QLabel("这是 label 组件");QPushButton* botton = new QPushButton("按钮");layout->addWidget(label);layout->addWidget(botton);// 依次进行添加contain->setLayout(layout);dock->setWidget(contain);
}

对话框

        对话框是 GUI 程序中不可或缺的组成部分。⼀些不适合在主窗⼝实现的功能组件可以设置在对话框中。对话框通常是⼀个顶层窗⼝,出现在程序最上层,⽤于实现短期任务或简洁的用户交互

        常见的对话框(QDialog 子类)

  • QFiledialog(⽂件对话框)
  • QColorDialog(颜⾊对话框)
  • QFontDialog(字体对话框)
  • QInputDialog(输⼊对话框)
  • QMessageBox(消息框)

        案例1:使用按钮点击,弹出一个简单的对话框

void MainWindow::on_pushButton_clicked()
{QDialog* dialog = new QDialog(this);// dialog 是 QWidget 的子类,QWidget的方法它都能使用dialog->resize(600,700);dialog->show();dialog->setAttribute(Qt::WA_DeleteOnClose);   
}

        QDialog 并没有再这之后 delete,它要等到 QMainWindow delete 后才 delete,但如果 QDialog 很大,用户多点击按钮创建就会造成内存泄漏,解决方法是用户点击 X 的信号进行关联实现释放 QDialog 的函数,但其实还有更简单的做法:QDialog 中设置属性 Qt::WA_DeleteOnClose 完成自动释放的工作

dialog->setAttribute(Qt::WA_DeleteOnClose);

        案例2:自己来创建对话框类,如果在该类中添加控件比如实现按钮来关闭该对话框

  • 使用代码:Qt 中创建类

        填写相关信息

//Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>// 使用 Dialog 继承 QDialog
class Dialog:public QDialog
{Q_OBJECT
public:Dialog(QWidget* parent = nullptr);
};#endif // DIALOG_H//Dialog.cpp
Dialog::Dialog(QWidget* parent):QDialog(parent)
{// 可以在这里给对话框新增控件QVBoxLayout* layout = new QVBoxLayout();// 添加组件使用 QVBoxLayout 管理QLabel *  label = new QLabel("这是一个关闭对话框的按钮");QPushButton* button = new QPushButton("关闭");layout->addWidget(label);layout->addWidget(button);// 再添加到 Dialog 中this->setLayout(layout);connect(button,&QPushButton::clicked,this,[&](){this->close();});
}

                案例1将 QDialog 替换为 Dialog

  • 使用 ui:创建设计师界面类

        设置相关信息

        完成后会多出三个文件,自己在 dialog.ui 下,以 ui 方式增加组件

        刚好生成的 dialog 类与前面类名相同,增加控件完成就可以运行查看结果

模态与非模态

        对话框有模态与非模态的概念:模态就是创建对话框后,不能操作父类窗口的各种控件;而非模态则可以,我们上面创建的对话框就是非模态

        要想变成模态只需要改一行代码即可

//dialog->show();
dialog->exec(); // 变成模态

        除了 QDialog 外,还通过它为父类设计出了很多具有各种属性的对话框

QMessageBox

        消息对话框,提示用户选择哪个操作去执行,通常是以模态对话框来使用; QMessageBox 提供了各种静态成员函数设置图标

void MainWindow::on_pushButton_clicked()
{QMessageBox* message = new QMessageBox(this);message->resize(300,300);message->setWindowTitle("这是一个消息对话框");message->setText("按下任意按钮");message->setIcon(QMessageBox::Question);// 按钮可以使用宏自动生成,如果不设置默认给OK按钮message->setStandardButtons(QMessageBox::Ok | QMessageBox::No | QMessageBox::Cancel);// 返回用户按下的按钮int button_result = message->exec();if(button_result == QMessageBox::Ok)qDebug()<<"Ok";// 因为 exec 方法执行时代码阻塞在函数中,所有这里也可以自行使用 delete 进行是否delete message;//message->setAttribute(Qt::WA_DeleteOnClose);
}

        自行添加按钮则还需要传入按钮角色,也就是提供的各种宏

// 也可以手动设置 -> conncet 关联槽函数
QPushButton* botton = new QPushButton("确认");
message->addButton(botton,QMessageBox::AcceptRole);
  • 也可以一键式设计对话框窗口
void MainWindow::on_pushButton_clicked()
{// 大写Warning是设置图标int result = QMessageBox::warning(this,"这是一个消息对话框","选择按钮",QMessageBox::Ok | QMessageBox::No);if(result == QMessageBox::Ok)qDebug()<<"OK";elseqDebug()<<"No";
}

QColorDialog

        颜色对话框,Qt 中的颜色对话框创建完就可以使用了,相当于已经内置了

        案例:获取用户选择的颜色设置主窗口背景色

void MainWindow::on_pushButton_clicked()
{
//    QColorDialog* color = new QColorDialog(this);
//    color->exec();// 也是可以一键式创建QColor color = QColorDialog::getColor(Qt::blue,this,"颜色对话框");char buff[1024] = {0};sprintf(buff,"background-color: rgb(%d,%d,%d);",color.red(),color.green(),color.blue());// 设置用户选择的背景色this->setStyleSheet(buff);
}

QFileDialog

        文件对话框,⽤于应⽤程序中需要打开⼀个外部⽂件或需要将当前内容存储到指定的文件

        案例:实现两个按钮:打开文件和保存文件(此处并没有去具体实现功能)

void MainWindow::on_pushButton_clicked()
{QString path = QFileDialog::getOpenFileName(this);qDebug()<<path;
}void MainWindow::on_pushButton_2_clicked()
{QString path = QFileDialog::getSaveFileName(this);qDebug()<<path;
}

QFontDialog

        字体对话框,用户选择字体相关信息后可以对某个空间上的文本进行设置

        案例:点击按钮出现字体对话框,通过它来设置按钮文本

void MainWindow::on_pushButton_clicked()
{bool ok = false;QFont font = QFontDialog::getFont(&ok,this);qDebug()<<font.family()<<' '<<font.pointSize();ui->pushButton->setFont(font);
}

QInputDialog

        输入对话框,让用户根据提示输入对应类型的数据,比如:int,float,QString

        案例:按钮触发输入对话框,获取用户输入的数据打印在终端下

void MainWindow::on_pushButton_clicked()
{
//    int result = QInputDialog::getInt(this,"整数输入框","输入一个整数:");
//    qDebug()<<result;
//    double result = QInputDialog::getDouble(this,"整数输入框","输入一个整数:");
//    qDebug()<<result;// 相当于 vector<string>QStringList list;list.push_back("111");list.push_back("222");QString result = QInputDialog::getItem(this,"条目选择","选择或者输入",list);qDebug()<<result;
}

以上便是全部内容,有问题欢迎在评论区指正,感谢观看!

http://www.dtcms.com/a/511432.html

相关文章:

  • [人工智能-大模型-20]:对比 Copilot 与国产替代方案(如通义灵码、百度Comate)
  • c语言和网站建设的关系平台网站开发可行性分析
  • gcc编译的过程及每个过程的作用
  • ROS2[Humble] -- URDF Tutorial- 02-multipleshapes
  • C#实现二维码和条形码生成与打印
  • C#WPF如何跳转页面
  • 【高并发服务器】八、Poller描述符监控类实现
  • 用vs2013网站开发四川最好的网络优化公司
  • 如何开发一个 IDEA 插件通过 Ollama 调用大模型为方法生成仙侠风格的注释
  • 【论文精读】Latent-Shift:基于时间偏移模块的高效文本生成视频技术
  • unity基础学习笔记<上>
  • C# WPF Dragablz使用记录 TabControl选项卡可拖拽为单独界面或停靠
  • 机器人场景落地步入技术验证阶段,微美全息加快创新势能探索AI多元路径变革
  • YOLOv4 核心内容笔记
  • 网站开发工程师待遇家庭网站建设
  • 医疗门户网站模板wordpress3.8
  • iOS的多线程下数据安全和内存泄漏以及工具使用监测内存泄漏
  • 『CMake』关于使用CMake构建项目时的现代/传统指令
  • 请被人做网站怎么做倒计时网站
  • App开发框架调研对比
  • Ubuntu下载以及安装详解以及应用安装
  • 亚马逊云代理:AWS的EC2, S3, RDS,Lambda具体简介
  • 2640. QYQ在艾泽拉斯
  • 基于 React + TypeScript + Fabric.js 构建一个封面生成器网站
  • 营销型电子商务网站品牌建设与推广思路
  • 更新网站 seo公司的管理方式与管理方法
  • BZV49-C22,115稳压二极管 NXP安世半导体 工业电源芯片 芯片解析
  • 职场发展—如何避雷垃圾公司
  • 【Linux篇】软链接vs硬链接:Linux文件系统中的两种引用机制
  • C++ list核心接口与实战技巧