C++ Qt学习笔记(2)简易计算器设计(为计算器添加菜单功能)
Qt中的主窗口为建立桌面应用程序的用户提供了一个框架,Qt中提供了QMainWindow和一些相关的类共同完成主窗口的管理。Qt中的QWidget是一个最基本的窗口控件,只有一个最基本的窗口,其余什么也没有。而QMainWindow为用户提供了一个具有菜单,工具栏以及底部状态栏的窗口。
1. 菜单栏
Qt中的菜单栏主要由QMenu和QAction类来表示。QMenu表示菜单对象,QAction表示菜单按下的事件。例如新建一个QMainWindow项目:
通过双击“在这里输入”来添加菜单以及添加子菜单。例如添加文件菜单,需要输入文件(&F),&F称为加速键,表明程序在运行时可以按下ALT+F键来激活菜单,添加子菜单的时候,可能会由于Qt版本问题无法输入中文。解决方法:再别的地方写好,再复制粘贴到菜单栏里面即可 新建(&N) 打开(&O)。
在新建完成菜单之后,可以看到,在Qt中的Action编辑器中已经出现了两个菜单,
将菜单和相应的槽函数相连接,有两种实现方法:
1. 右击按钮,点击跳转到槽选项,Qt会自己创建相应的槽函数,编写业务代码即可
2. 在QMainWindow.h文件中自定义槽函数,然后通过connect函数将菜单与相应的槽函数相连。
private slots: void on_action_N_triggered(); void on_action_O_triggered();
connect(ui->action_O, SIGNAL(triggered()), this, SLOT(on_action_O_triggered)); // 通过connect函数也可以连接
2. 工具栏
工具栏QToolBar类提供了一个包含一组控件,且可以移动的面板。在工具栏中,可以添加其他的窗口控件,例如可以添加弹出菜单以及非弹出菜单。
在工具栏中添加新的弹出式 的菜单,以及添加spinbox控件:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect(ui->action_O, SIGNAL(triggered()), this, SLOT(on_action_O_triggered)); // 通过connect函数也可以连接 // 添加工具栏内容 按钮类型 QToolButton* toolbtn = new QToolButton(this); toolbtn->setText("Color"); // 为按钮添加菜单 QMenu* colormenu = new QMenu(this); colormenu->addAction("red"); colormenu->addAction("pink"); toolbtn->setMenu(colormenu); toolbtn->setPopupMode(QToolButton::MenuButtonPopup); // 将按钮添加到工具栏 ui->mainToolBar->addWidget(toolbtn); // 将一个spinbox添加到工具栏 QSpinBox* spinbox = new QSpinBox(this); spinbox->setMaximum(100); spinbox->setMinimum(0); spinbox->setValue(50); ui->mainToolBar->addWidget(spinbox); // 将新建按钮QAction添加到工具栏 ui->mainToolBar->addAction(ui->action_N); }
工具栏效果如图所示:
3.状态栏
状态栏QStatusBar提供了一个水平条控件,用于向用户显示状态信息。QMainWindow中提供一个默认的状态栏。
状态栏中的信息分为三类:
1.临时信息,如一般的提示性的信息
2. 正常信息:例如显示当前的页码以及行号‘
3. 永久信息:显示版本号或者日期
可以使用showMessage()函数显示临时信息,它会出现在状态栏的最左边。一般添加一个Qlabel到状态栏上显示正常信息,它也会出现在状态栏的左边,可能被临时信息覆盖。如果需要显示永久信息,则需要使用addPermanentWidget()添加一个类似于Qlabel的可以显示信息的控件,他会生成在状态栏的右边。
// 向状态栏中添加信息 QLabel* normal_info = new QLabel(this); QLabel* permanent_info = new QLabel(this); normal_info->setText("Normal information"); permanent_info->setText("Permanent infomation"); // 向状态栏添加相应的控件 ui->statusBar->addWidget(normal_info); ui->statusBar->addPermanentWidget(permanent_info);
如果需要显示提示信息,则需要调用:
ui->statusBar->showMessage("New file Created!"); // 显示提示信息
可以将提示信息的显示写入相应的槽函数中,例如为新建按钮添加提示信息:
void MainWindow::on_action_N_triggered() { qDebug() << "The new file button pushed" << endl; ui->statusBar->showMessage("New file Created!"); // 显示提示信息 }
则在新建按钮按下后,会出现提示信息,覆盖掉正常信息,但是当进行别的操作的时候,提示信息会消失,显示正常的信息。
4. 对话框
对话框窗口是一种比较特殊的窗口,对话框窗口通常用来完成短小任务或者和用户进行简单交互的顶级窗口,QDialog是所有对话框窗口的基类,下面介绍几种标准的对话框:
1. 模态与非模态对话框
按照运行对话框时,是否还可以与该程序的其他窗口进行交互,对话框可以分为两类,模态和非模态。
例如:对于上述的open菜单,设计一个对话框,非模态对话框就是当对话框弹出时,用户任然可以和其他的窗口进行交互。模态对话框则不行,只有将对话框关闭,才可以和其他的对话框进行交互。
void MainWindow::on_action_N_triggered() { qDebug() << "The new file button pushed" << endl; ui->statusBar->showMessage("New file Created!"); // 显示提示信息 // 创建一个模态对话框 QDialog* dialog_new = new QDialog(this); dialog_new->setModal(true); dialog_new->show(); } void MainWindow::on_action_O_triggered() { // 创建一个非模态对话框 QDialog* dialog_open = new QDialog(this); dialog_open->setModal(false); // 非模态 dialog_open->show(); // qDebug() << "The open file button pushed" << endl; }
通过dialog的setModal()函数设置对话框是模态还是非模态。
2. 自定义对话框
上述的对话框都是直接使用了QDialog类,这样的对话框时是空白的,里面没有其他的东西,为了能够使用Qt Designer来设计对话框,则需要继承QDialog类来设计一个自定义的会话框。
选中项目->右击选择“添加文件”->Qt Designer界面类,界面类模板选择Dialog without buttons, 类名默认即可。创建成功后,会自动转到设计模式,就可以进行设计了。
继续选择:
创建完成后,跳转到设计界面,此时在生成.ui文件的同时,也生成了对应的.cpp以及.h文件。
例如可以在对话框中拖入两个按钮:
然后在diaog.h文件以及dialog.cpp文件中,将按钮与相应的槽函数绑定:
1. 在dialog.h中定义槽函数:
private slots: void dialog_btn_ok();
2. 在dialog.cpp中连接按钮信号和槽函数:
connect(ui->dialog_btn_ok, SIGNAL(clicked()), this, SLOT(dialog_btn_ok())); // 连接槽函数 connect(ui->dialog_btn_cancel, SIGNAL(clicked()), this, SLOT(close())); // 关闭对话框
这样,就完成了对话框中信号和槽的连接。
在QMainWindow中调用设计的对话框:QMainWindow.cpp中需要include dialog.h文件即可
void MainWindow::on_action_O_triggered() { Dialog* dialog_open = new Dialog(this); dialog_open->setModal(true); dialog_open->show(); // qDebug() << "The open file button pushed" << endl; }
效果如下所示:
3. 标准对话框:
Qt为用户提供了一些常用的对话框,同样他们也继承自QDialog类,并且增加了特定的功能,例如获取颜色以及显示特定信息等。下面分别介绍这些对话框。
首先需要将相应的头文件包含到程序中:
#include <QColorDialog> // 颜色 #include <QFontDialog> // 字体 #include <QMessageBox> // 消息 #include <QErrorMessage> // 错误信息 #include <QFileDialog> // 文件 #include <QInputDialog> // 输入 #include <QProgressDialog> // 进度 #include <QWizard> // 向导
在设计模式下,向QMainWindow中拖入按钮,并且修改按钮的属性和名称:
定义按钮对应的槽函数:
// 标准对话框 void dialog_color(); // 颜色对话框 void dialog_font(); // 字体对话框 void dialog_info(); // 消息对话框 void dialog_error(); // 错误消息对话框 void dialog_file(); // 文件对话框 void dialog_input(); // 输入对话框 void dialog_progress(); // 进度对话框 void dialog_navi(); // 向导对话框
连接按钮与对应的槽函数:
void MainWindow::connect_dialogs() { connect(ui->btn_dialog_color, SIGNAL(clicked()), this, SLOT(dialog_color())); connect(ui->btn_dialog_error, SIGNAL(clicked()), this, SLOT(dialog_error())); connect(ui->btn_dialog_file, SIGNAL(clicked()), this, SLOT(dialog_file())); connect(ui->btn_dialog_font, SIGNAL(clicked()), this, SLOT(dialog_font())); connect(ui->btn_dialog_info, SIGNAL(clicked()), this, SLOT(dialog_info())); connect(ui->btn_dialog_input, SIGNAL(clicked()), this, SLOT(dialog_input())); connect(ui->btn_dialog_navi, SIGNAL(clicked()), this, SLOT(dialog_navi())); connect(ui->btn_dialog_progress, SIGNAL(clicked()), this, SLOT(dialog_progress())); }
1. 颜色对话框:
可以使用QColorDialog的静态方法getColor,这样不需要声明对象:
// 1. 颜色对话框 void MainWindow::dialog_color() { // 使用QColorDialog直接显示对话框,无需创建对象 QColor color = QColorDialog::getColor(Qt::red, this, "Color"); // 参数: 初始颜色 父窗口 窗口标题 qDebug() << "color: " << color; }
如果需要更加灵活的设置颜色对话框,可以通过创建对象来实现:
// 1. 颜色对话框 void MainWindow::dialog_color() { QColorDialog* color_dialog = new QColorDialog(Qt::red, this); color_dialog->setOption(QColorDialog::ShowAlphaChannel); // 显示alpha通道 color_dialog->exec(); QColor color = color_dialog->currentColor(); // 获取当前的颜色 qDebug() << "Color: " << color << endl; }
颜色对话框如下图所示:
2. 错误消息对话框
错误消息对话框QErrorMessage类提供了一个现实错误消息的对话框,它的使用方法如下所示:
// 2. 错误消息对话框 void MainWindow::dialog_error() { QErrorMessage* error_dialog = new QErrorMessage(this); // 创建对话框 error_dialog->setWindowTitle("Error"); // 设置对话框标题 error_dialog->showMessage("An operation error accured"); // 设置对话框的错误信息 }
错误消息对话框如下所示:
3. 文件对话框:
文件对话框QFileDialog为用户提供了一个允许用户选择文件或者文件夹的界面。使用方式如下所示:
// 3. 文件对话框 void MainWindow::dialog_file() { // 获取一个文件名,可以使用静态方法getOpenFileName // 获取多个文件名,使用静态方法getOpenFileNames // 函数参数分别是:对话框的父窗口 对话框标题 打开时的默认路径 文件过滤器(Pictures格式需要加空格),以";;"进行分隔 QString file_name = QFileDialog::getOpenFileName(this, "File open", "D:", "Pictures(* png * jpg);;TXT(*txt)"); qDebug() << "Filename is: " << file_name << endl; }
对话框如下:
4. 字体对话框:
向用户提供一个可以选择字体的对话框:
// 4. 字体对话框 void MainWindow::dialog_font() { bool ok = false; // 用来判断用户是否选择了字体 QFont font = QFontDialog::getFont(&ok, this); // 获取字体 if(ok) { qDebug() << "Font: " << font << endl; ui->btn_dialog_font->setFont(font); // 将font按钮的字体改编为选择的字体 } else { qDebug() << "Not select font" << endl; } }
字体对话框如下所示:
可以看到,在选择字体后,字体按钮所对应的字体发生了变化:
5. 消息对话框:
消息对话框提供一个模态的对话框来通知用户一些信息,或者向用户提出问题并获取答案,具体的使用如下所示:
// 5. 消息对话框 void MainWindow::dialog_info() { // 提问对话框,用于和用户交互简单问题 int ret1 = QMessageBox::question(this, "Question dialog", "Do u know Qt?", QMessageBox::Yes, QMessageBox::No); if(ret1==QMessageBox::Yes) { qDebug() << "Very goood"; } // 提示对话框 int ret2 = QMessageBox::information(this, "Tip dialog", "This is a book about Qt", QMessageBox::Yes); if(ret2==QMessageBox::Yes) { qDebug() << "This is a tip"; } // 警告对话框 int ret3 = QMessageBox::warning(this, "waring dialog", "You can not operate", QMessageBox::Abort); if(ret3==QMessageBox::Abort) { qDebug() << "This is a warning" << endl; } // 严重错误对话框 int ret4 = QMessageBox::critical(this, "criticalerror dialog", "An critical occured!", QMessageBox::YesAll); if(ret4==QMessageBox::YesAll) { qDebug() << "Error happen" << endl; } QMessageBox::about(this, "about dialog", "Qt dialog object"); }
上面的实例中展示了不同的消息对话框,按照重要等级递进:
a1. 问题对话框:和用户进行简单的交互
a2. 提示对话框,对用户进行简单的提示
a3. 警告对话框,提示可能会 发生的错误
a4. 严重错误对话框,告知用户发生严重错误
a5.关于对话框
--------------------------------------------------------------------------------------------------------------------------------
6. 输入对话框:
输入对话框QInputDialog类用来提供一个输入对话框,用户可以输入单一的数值或者字符串。
// 6. 输入对话框 void MainWindow::dialog_input() { bool ok; // 获取输入的文本信息 // getText()参数 父窗口 标题 label 输入框 默认字符串 ok QString name = QInputDialog::getText(this, "Input Dialog", "Name", QLineEdit::Normal, "Admin", &ok); if(ok) { qDebug() << "name: " << name << endl; } // 获取输入的数值信息 // getInt()参数:父窗口 标题 label 默认数值 最小值 最大值 步长 ok int ret = QInputDialog::getInt(this, "Input Dialog", "age", 20, 10, 100, 1, &ok); if(ok) { qDebug() << "Age: " << ret << endl; } // 获取输入的数值信息 double salary = QInputDialog::getDouble(this, "Input Dialog", "Salary", 20000, 5000, 100000, 500.45, &ok); if(ok) { qDebug() << "Salary: " << salary << endl; } // 相当于一个多选一的对话框,下拉的选择菜单 QStringList items; items << "male" << "female"; // 对话框内容 QString item = QInputDialog::getItem(this, "Input dialog", "Select sex", items, 0, true, &ok); if(ok) { qDebug() << "Sex: " << item; } }
输入对话框可以实现用户输入字符串,数值,下拉菜单选择等。
a1. 输入字符串:
a2. 输入数值:
a3. 下拉菜单:
7. 向导对话框:
QWizard是向导对话框,它向用户提供了一个设计向导界面的框架,例如,安装软件以及创建项目的时候,就是典型的向导对话框。Qwizard是一个向导对话框的框架,它可以设计一个向导全部的功能函数,需要首先创建出向导页面WizardPage,然后将向导页面添加到向导对话框。
a1, 定义首先创建向导页面的函数:
private: // 创建导航页面 QWizardPage* create_page1(); QWizardPage* create_page2(); QWizardPage* create_page3(); // 创建导航页 QWizardPage* MainWindow::create_page1() { QWizardPage* page = new QWizardPage(this); page->setTitle("Recommendation"); return page; } QWizardPage* MainWindow::create_page2() { QWizardPage* page = new QWizardPage(this); page->setTitle("Custom choose infmation"); return page; } QWizardPage* MainWindow::create_page3() { QWizardPage* page = new QWizardPage(this); page->setTitle("End"); return page; }
a2. 创建向导对话框:
// 7. 向导对话框 void MainWindow::dialog_navi() { QWizard wizard(this); // 创建一个导航窗口对象 wizard.setWindowTitle("Wizard dialog"); wizard.addPage(create_page1()); // 添加页面 wizard.addPage(create_page2()); wizard.addPage(create_page3()); wizard.exec(); }
向导对话框页面:
8. 进度条对话框:
对一个时间较长的操作提供时间反馈:
// 8. 进度对话框 void MainWindow::dialog_progress() { QProgressDialog progress_dialog("File copy progress", "Cancel", 0, 5000, this); progress_dialog.setWindowTitle("Copy file"); progress_dialog.show(); for(int i=0; i<50000; i++) { progress_dialog.setValue(i); QCoreApplication::processEvents(); // 避免长时间操作而使用户界面冻结 if(progress_dialog.wasCanceled()) { break; } } progress_dialog.setValue(50000); qDebug() << "copy finished" << endl; }
给app添加图标:
第一步;将图片转化为.ico文件:
网上的免费工具即可完成转换: http://www.bitbug.net/
第二步: 将.ico文件放入到目录中:
第三步:
在pro文件中,添加以下代码:
RC_ICONS += appico.ico
但是我的顿操作之后并没有显示,百度也没有解决,再查查看
------------------------------------------------------------------------------------------------------------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)