目录
窗口的组成
菜单栏
图形化创建菜单栏
代码创建菜单栏
给菜单设置快捷键
添加子菜单
添加分割线
添加图标
工具栏
设置工具栏出现的初始位置(上下左右)
设置工具栏允许停靠的位置
设置不允许浮动
设置不允许移动
状态栏
创建状态栏
显示实时消息
给状态栏添加子控件
浮动窗口
1. 给主窗口添加一个浮动窗口(子窗口)
2. 给浮动窗户设置标题
3.给浮动窗口内部,添加一些其他控件
4. 设置浮动窗口的停靠位置
对话框
对话框介绍
分类
内存释放问题
创建对话框
自定义对话框
通过代码实现自定义
通过图形化自定义
模态对话框
消息对话框
1. 创建消息对话框
2. 设置对话框窗口标题和文本
3.设置对话框风格
4.设置对话框包含的按钮
5. 获取用户点击哪个按钮
简便写法
颜色对话框
常用方法
使用示例:基于用户选择的颜色,修改窗口的背景色
文件对话框
常用方法
字体对话框
输入对话框
窗口的组成
Qt中窗口是通过QMainWindow类来实现的,QMainWindow是一个为用户提供主程序的类,继承自QWidget类,并且提供了⼀个预定义的 布局。QMainWindow 包含 ⼀个菜单栏(menu bar)、多个⼯具栏(tool bars)、多个浮动窗⼝(铆接部件)(dock widgets 也就是子窗口)、⼀个状态栏(status bar) 和⼀个 中⼼部件(central widget)
菜单栏跟工具栏的区别 :
菜单栏如下:
工具栏如下:
工具栏中本质上就是菜单栏中一些选项的快捷方式。
菜单栏
一个主窗口最多只能有一个菜单栏。
菜单项通过QAction类实现。
图形化创建菜单栏
在 这里的 “在这里输入” 是新建一个菜单页
在文件下拉选项中的 是新建一个菜单项
代码创建菜单栏
1. 创建菜单栏
QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);
2. 创建菜单
QMenu* menu1 = new QMenu("文件");
QMenu* menu2 = new QMenu("编辑");
QMenu* menu3 = new QMenu("视图");
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
menuBar->addMenu(menu3);
3. 给菜单添加菜单项
QAction* action1 = new QAction("新建");
QAction* action2 = new QAction("打开");
QAction* action3 = new QAction("保存");
menu1->addAction(action1);
menu1->addAction(action2);
menu1->addAction(action3);
4. 给action添加信号槽
connect(action1,&QAction::triggered,this,&MainWindow::handle);
5. 效果如下:
给菜单设置快捷键
设置好的快捷键搭配alt就可以进行使用了
QMenu* menu1 = new QMenu("文件(&F)");
通过给文本设置 “ (&F)” 即可设置快捷键,与QLabel设置伙伴类似。
菜单项的快捷键与这一样。
添加子菜单
菜单栏通过 addMenu 添加菜单,菜单也是通过addMenu 添加子菜单。
示例:
QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);
QMenu* menuParent = new QMenu("父菜单");
QMenu* menuChild = new QMenu("子菜单");
QAction* action1 = new QAction("菜单项1");
QAction* action2 = new QAction("菜单项2");;
menuBar->addMenu(menuParent);
menuParent->addMenu(menuChild);
menuParent->addAction(action1);
menuParent->addAction(action2);
效果如下:
添加分割线
菜单里菜单项特别多,就可以通过分割线,进行分组。
QMenu中提供了 addSeparator 函数。
这是添加分割线之前的效果:
添加之后:
代码如下:
menuParent->addAction(action1);
menuParent->addSeparator();
menuParent->addAction(action2);
通过这个分割线,可以把菜单中若干个菜单项分成几个部分,以达到更好的用户体验效果。
添加图标
这里涉及到之前所介绍的QIcon类和qrc机制。
代码如下:
QAction* action1 = new QAction("编辑");
action1->setIcon(QIcon(":/edit.png"));
效果如下:
菜单也可以设置图标,但是如果给QMenu设置图标 ,当前的QMenu是长在QMenuBar上的,此时文本就不显示,图标覆盖了文本,如果当前的QMenu是子菜单,图标和文本是都能显示的。
创建menuBar的细节
QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);
上述代码中,在一些多线程之类的情况下,可能会出现原本窗口已经有了菜单栏,我们在进行设置菜单栏的话,会导致原本的菜单栏脱离对象树,从而导致后续内存泄漏。
因此我们可以规范一下创建菜单栏的写法:
QMenuBar* menuBar = this->menuBar();
this->setMenuBar(menuBar);
上述代码写法的好处:
- 如果QMenuBar已经存在,直接获取并返回。
- 如果QMenubar不存在,就先创建一个新的,再返回。
如果是获取到已经存在的QMenuBar,后面的设置就是自己替换自己,还在对象树上。
工具栏
qt中使用QToolBar表示工具栏对象,一个窗口可以有多个工具栏,也可以没有,同时工具栏往往可以手动移动位置。
使用示例:
QToolBar* toolBar = new QToolBar();
this->addToolBar(toolBar);
QAction* action1 = new QAction("保存");
action1->setIcon(QIcon(":/edit.png"));
toolBar->addAction(action1);
效果:
可以从上述效果中看出,文本被图标所覆盖,但是我们设置的文本并没有消失 ,而是变成tooltip存在。
设置工具栏出现的初始位置(上下左右)
- Qt::LeftToolBarArea 停靠在左侧
- Qt::RightToolBarArea 停靠在右侧
- Qt::TopToolBarArea 停靠在顶部
- Qt::BottomToolBarArea 停靠在底部
- Qt::AllToolBarAreas 以上四个位置都可停靠
示例:
QToolBar* toolBar = new QToolBar();
this->addToolBar(Qt::LeftToolBarArea,toolBar);
设置工具栏允许停靠的位置
示例:允许左侧和右侧停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea)
设置不允许浮动
toolBar->setFloatable(false);
设置不允许移动
toolBar->setMovable(false);
状态栏
- 实时消息:如当前程序状态
- 永久消息:如程序版本号,机构名称
- 进度消息:如进度条提⽰,百分百提⽰
创建状态栏
用如下的方式创建状态栏,若原本状态来就存在就获取即可,不存在就创建一个。
QStatusBar* statusBar = this->statusBar();
this->setStatusBar(statusBar);
显示实时消息
第二个参数为显示的时间,如下是显示2秒,如果为0或者不填,则消息永久存在。
statusBar->showMessage("hello",2000);
给状态栏添加子控件
addWidget( ) 在状态栏左侧添加控件
addPermanentWidget( ) 在状态栏右侧添加控件
statusBar->addWidget(label1);
statusBar->addPermanentWidget(label2);
效果如下:
浮动窗口
浮动窗口也就是子窗口。
Qt中使用QDockWidget 来实现的。
1. 给主窗口添加一个浮动窗口(子窗口)
QDockWidget* dockWidget = new QDockWidget();
this->addDockWidget(Qt::LeftDockWidgetArea,dockWidget);
2. 给浮动窗户设置标题
dockWidget->setWindowTitle("这是浮动窗口");
3.给浮动窗口内部,添加一些其他控件
不能直接给这个浮动窗口添加子控件,而是需要创建出一个单独的QWidget,把要添加的控件加入到QWidget中。,然后再把这个QWidget设置到dockWidget中。
由于dockWidget中只能包含一个QWidget,想要添加更多控件只能往这个QWidget中进行添加了。
QWidget* container = new QWidget();
dockWidget->setWidget(container);
QVBoxLayout* layout = new QVBoxLayout();
container->setLayout(layout);
QLabel* label = new QLabel("标签1");
QPushButton* btn = new QPushButton("按钮");
layout->addWidget(label);
layout->addWidget(btn);
效果如下:
4. 设置浮动窗口的停靠位置
- Qt::LeftDockWidgetArea 停靠在左侧
- Qt::RightDockWidgetArea 停靠在右侧
- Qt::TopDockWidgetArea 停靠在顶部
- Qt::BottomDockWidgetArea 停靠在底部
- Qt::AllDockWidgetAreas 以上四个位置都可停靠
示例:设置浮动窗口只允许上下停靠
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
对话框
对话框介绍
分类
内存释放问题
因为dialog可以存在多个,可能会存在内存泄漏的问题,所以我们应该让用户点击 对话框关闭按钮的时候,触发delete操作。
dialog->setAttribute(Qt::WA_DeleteOnClose);
创建对话框
1. 创建对话框
QDialog* dialog = new QDialog(this);
2. 设置对话框标题
dialog->setWindowTitle("对话框的标题");
3. 设置对话框尺寸
dialog->resize(400,300);
4. 显示对话框
dialog->show();
5. 设置delete属性
dialog->setAttribute(Qt::WA_DeleteOnClose);
自定义对话框
要想自定义对话框,就需要继承QDialog创建类。
通过代码实现自定义
这里我们新建一个类,如下:
1. Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QWidget>
#include <QDialog>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget* parent);
void handle();
};
#endif // DIALOG_H
2. Dialog.cpp
#include "dialog.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
Dialog::Dialog(QWidget* parent):QDialog(parent)
{
QVBoxLayout* layout = new QVBoxLayout();
this->setLayout(layout);
QLabel* label = new QLabel("这是一个对话框",this);
QPushButton* btn = new QPushButton("关闭",this);
layout->addWidget(label);
layout->addWidget(btn);
connect(btn,&QPushButton::clicked,this,&Dialog::handle);
}
void Dialog::handle()
{
this->close();
}
3. 调用
void MainWindow::on_pushButton_clicked()
{
Dialog* dialog = new Dialog(this);
dialog->setWindowTitle("这是自定义对话框");
dialog->resize(400,300);
dialog->show();
}
4. 效果
通过图形化自定义
1. 新建一个Qt设计师界面
2.选择模板
3.这样会多出来一个ui文件
4. 在dialog 的ui文件中设计自定义对话框即可
模态对话框
模态:弹出对话框的时候,此时用户无法操作父窗口,必须得完成对话框内部出的操作,关闭对话框之后,才可操作父窗口。
非模态:弹出对话框的时候,用户可以操作父窗口。
那么我们如何产生模态对话框呢?
把前面 .show方法换成exec即可。
dialog->exec();
消息对话框
消息对话框 QMessageBox,消息对话框是应⽤程序中最常⽤的界⾯元素。消息对话框主要⽤于为⽤⼾提⽰重要信息,强制⽤⼾进⾏选择操作。
1. 创建消息对话框
QMessageBox* message = new QMessageBox(this);
2. 设置对话框窗口标题和文本
message->setWindowTitle("对话框窗口标题"); message->setText("这是对话框文本");
3.设置对话框风格
QMessageBox类 中定义了静态成员函数,可以直接调⽤创建不同⻛格的消息对话框,其中包括:
Question ⽤于正常操作过程中的提问 Information ⽤于报告正常运⾏信息 Warning ⽤于报告⾮关键错误 Critical ⽤于报告严重错误
message->setIcon(QMessageBox::Warning);
4.设置对话框包含的按钮
message->setStandardButtons(QMessageBox::Ok | QMessageBox::Save);
除了使用系统提供按钮,我们也可以添加自己的按钮 ,在添加按钮的时候,可以设置按钮的角色
代码如下:
QPushButton* btn = new QPushButton("按钮",messageBox);
messageBox->addButton(btn,QMessageBox::AcceptRole);
也可以给这个按钮绑定信号槽来使用。
5. 获取用户点击哪个按钮
用户点击按钮,使对话框关闭之后,此时就能通过exec的返回值,来知道用户点击的是哪个按钮,从而执行一些对应的逻辑。
以下是系统自带的按钮:
代码示例:
int result = messageBox->exec();
if(result == QMessageBox::Ok){
qDebug()<<"ok"<<endl;
}
因为QMessageBox的使用场景一般是模态的,所以我们使用exec方法
简便写法
通过warning这个静态函数,可以快速的构造出一个消息对话框。
int result = QMessageBox::warning(this,"对话框标题","对话框文本",QMessageBox::Ok | QMessageBox::No);
if(result == QMessageBox::Ok){
qDebug()<<"ok"<<endl;
}
另外三种也可以通过上述的方法。
颜色对话框
常用方法
1、 QColorDialog (QWidget *parent = nullptr) //创建对象的同时设置⽗对象2、 QColorDialog(const QColor &initial, QWidget *parent = nullptr) //创建对象的同时通过QColor对象设置默认颜⾊和⽗对象3、 void setCurrentColor(const QColor &color) //设置当前颜⾊对话框4、 QColor currentColor() const //获取当前颜⾊对话框5、 QColor getColor(const QColor &initial = Qt::white,QWidget *parent = nullptr,const QString &title = QString(),QColorDialog::ColorDialogOptions options = ColorDialogOptions()) //打开颜⾊选择对话框,并返回⼀个QColor对象参数说明:initial:设置默认颜⾊parent:设置⽗对象title:设置对话框标题options:设置选项6、 void open(QObject *receiver, const char *member) //打开颜⾊对话框
使用示例:基于用户选择的颜色,修改窗口的背景色
QColor(ARGB 1, 0.541176, 0.27451, 1)
第一个参数为不透明度,1 为不透明 ,接下去的参数为red 、green 、blue
QColor color = QColorDialog::getColor(QColor(0,255,0),this,"选择颜色");
qDebug()<<color;
QString style = "background-color: rgb(" + QString::number(color.red()) + "," +
QString::number(color.green()) + "," +QString::number(color.blue()) + ");";
this->setStyleSheet(style);
文件对话框
常用方法
1、打开⽂件(⼀次只能打开⼀个⽂件)QString getOpenFileName (QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())2、打开多个⽂件(⼀次可以打开多个⽂件)QStringList getOpenFileNames (QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())3、 保存⽂件QString getSaveFileName (QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())参数说明:参数1: parent ⽗亲参数2: caption 对话框标题参数3: dir 默认打开的路径参数4: filter ⽂件过滤器
此处的打开/保存功能需要额外去实现的,并不是说直接一按保存就真的保存了
代码示例:
返回文件路径
QString filePath = QFileDialog::getOpenFileName(this);
QString filePath = QFileDialog::getSaveFileName(this);
字体对话框
bool ok = false;
QFont font = QFontDialog::getFont(&ok);
qDebug()<<font.family();
qDebug()<<font.pointSize();
qDebug()<<font.bold();
qDebug()<<font.italic();
使用示例:基于用户选择的font属性,设置button的字体
ui->pushButton->setFont(font);
输入对话框
让用户输入一个具体的数据,可以是整数、浮点数,也可以是字符串。
1、双精度浮点型输⼊数据对话框double getDouble (QWidget *parent, const QString &title, const QString &label, doublevalue = 0, double min = -2147483647, double max = 2147483647, int decimals = 1, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());2、整型输⼊数据对话框int getInt (QWidget *parent, const QString &title, const QString &label, int value = 0, intmin = -2147483647, int max = 2147483647, int step = 1, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());3、选择条⽬型输⼊数据框QString getItem (QWidget *parent, const QString &title, const QString &label, constQStringList &items, int current = 0, bool editable = true, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags(), Qt::InputMethodHints inputMethodHints = Qt::ImhNone) ;参数说明:parent:⽗亲title:对话框标题label:对话框标签items:可供选择的条⽬返回值为用户输入的值字符串数组 QStringList item
这里演示条目输入框的用法:
QStringList items;
items.push_back("111");
items.push_back("222");
items.push_back("333");
QString item = QInputDialog::getItem(this,"条目输入对话框","请输入条目",items);
效果如下: