前言
命名规范:类名首字母大写,单词与单词之间大写;函数名首字母小写,单词与单词之间大写
快捷键:
注释:ctrl+/
运行: ctrl+r
编译:ctrl+b
整行移动:ctrl+shift+上or下
帮助文档:F1
自动对齐:ctrl+i
xxx.cpp文件和xxx.h文件之间快速切换:F4
一、第一个QT程序
创建一个桌面QT应用程序,选择如下
choose下一步
继续下一步
这里有三个选择分别是QMainWindow,QDialog,Qwidget,这里的QWidget相当于其他两个父类,选择QWidget就是一个空的窗口,选择QMainWindow会在空窗口的基础上多了菜单栏,QDialog就是对话窗类,下面有个创建界面,如果不勾选就是自己编写程序的窗口各种组件,如果勾选了就可以类似MFC在一个空的窗口自己添加各种组件设计界面。继续下一步完成创建
打开文件中的widget.ui文件就会跳转到添加组件界面,这里添加两个组件
先打开01_learn.pro文件添加语句
QT += core gui texttospeech
然在在ui界面右击按钮,选择跳转到槽,然后选择clicked,然后会跳转到相应的控制组件的相应语句在其实添加事件处理程序
x->say(ui->lineEdit->text());
再编写Wdiget的构造函数添加语句
由于这里使用了QTextTOSpeeh所以还要在widget.h文件中添加该类的头文件
最后在运行程序
在文本框中输入文字,点击按钮就会语音播报出这段文字
二、基本认识
文件目录
.pro文件
第一个pro是项目工程文件文件
#-------------------------------------------------
#
# Project created by QtCreator 2022-11-21T19:30:51
#
#-------------------------------------------------
QT += core gui texttospeech #QT包含的模块,这个时候里面有三个模块分别是core gui texttospeech
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets #大于4版本包含widget模块
TARGET = hello #目标 生成.exe可执行文件的名称
TEMPLATE = app #模板 应用程序模板,默认生成的是app模板,也有别的一些模板
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS #表示当Qt的某些功能被标记为过时的,那么编译器会发出警告。
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \ #源文件
main.cpp \
widget.cpp
HEADERS += \ #头文件
widget.h
FORMS += \ #ui文件
widget.ui
main.cpp
main.cpp是主函数文件,里面包含了主要应用程序的入口函数,和C/C++一般写法一样,QT界面的main()函数也有固定的格式
int main(int argc,char **argv){
QApplication a(argc,argv);
return a.exec();
}
图中的main()函数代码解析:
1~2行:由于在main()函数中分别定义了 QApplication和Widget类的对象,因此要引入两个文件的头文件。由于widget.h是我们自己创建的,所以引用的时候要用 “ “;QApplication是QT提供的所以用 < >;
7行:Widget是自定义的类,继承自QWidget,QWidget类是所有用户界面对象的基类,所有Widget也是,w是实例化出的一个用户界面
8行: 在默认的情况下,QT所提供的所有组件都是隐藏的不会自动显示出来。通过调用show()方法,w用户界面就可以在程序运行后显示出来
#include "widget.h" //用户自定义的头文件,名字可以在创建的时候更改
#include <QApplication> //应用程序头文件,
int main(int argc, char *argv[])// argc是命令个数,argv是命令参数
{
QApplication a(argc, argv); //定义一个应用程序类,并且在每个QT文件中有且仅有一个应用程序类
//它的构造函数接受和main函数一样的参数,相当于c/c++程序中的程序入口,这个是QT图形化程序入口
Widget w;//创建一个窗口
w.show();//默认不会显示窗口,显示窗口
return a.exec();//会进入QT程序的事件循环函数等待用户的操作,图形程序需要与用户交互所以不会自动退出,当且仅当点击“X”之后就会返回一个0值关闭窗口
}
widget.cpp和widget.h
创建项目的时候定义了继承自QWidget的用户界面类,使用的默认名称widget,该类的定义部分位于widget.h头文件中,实现部分在widget.cpp文件中
//
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget> //添加的窗口类
#include <QTextToSpeech> //说话类
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT //定义好的宏,允许使用信号和槽机制
public:
explicit Widget(QWidget *parent = 0); //构造函数
~Widget(); //析构函数
private slots:
void on_pushButton_clicked(); //按钮
private:
Ui::Widget *ui;
QTextToSpeech *x; //创建说话对象
};
#endif // WIDGET_H
---------------------------------
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
x = new QTextToSpeech;
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
x->say(ui->lineEdit->text()); //提取框中文字语音播报
}
在初始的状态下widget类是由Q_OBJECT,构造函数还有析构函数组成的
- Q_OBJECT:本质是一个已经定义好的宏,所有需要的”信号和槽”功能组件都必须将Q_OBJECT作为private属性的成员引入类中。
- 带参数的构造函数:QWidget是所有组件的基类,借助parent指针,可以为当前窗口指定父窗口,如果删除父窗口,里面所有的子窗口都会关掉
后面两个prviate是自己添加的组件时QT自动添加的
运行结果在w主窗口中有两个自己添加的组件
widget.ui
这个文件中就是设计图形界面的,在这里添加的组件QT都会自动在相应的文件中生成,这时候只需要去对应的代码区写事件处理程序。
三、创建一个QPushButton
先创建一个新的项目my_PushButton,这次设置不创建界面,通过API接口添加组件。
如果第一次接触一个组件不知都怎么使用可以使用QT的界面中的帮助选项,这里以QPushButton为例
在QPushButton Class一栏中包含了使用所需要在文件中添加的内容
Header: #include <QPushButton> //使用所包含的头文件
qmake: QT += widgets //使用要添加的模块
Inherits: QAbstractButton //QPUshButton的父类
Inherited By: QCommandLinkButton //QPushButton的子类
在widget.cpp文件中添加控件,注意不是main.cpp
#include "widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//创建一个按钮
QPushButton *bt=new QPushButton; //这里要采用new的方式创建组件
}
Widget::~Widget()
{
}
这样就创建好了一个简单的按钮,但是运行编译发现,界面并没有出现按钮,之前说过默认是不会显示窗口的,那我们用show试一下
我们发现是没有在一个窗口上的,我们所期望的是按钮的就在我们初始创建的窗口上,所以我们把令bt的对象指向初始窗口
bt->setParent(this);//因为在窗口类里创建的对象,所以用this指针就可以指向窗口
设置这个按钮的文本
bt->setText("我的按钮");
这样创建其实是蛮麻烦的,QPushButton类中有多个重载的构造函数,利用重载构造函数我们可以快速创建出一个按钮组件
根据构造函数参数表我们所用第二个就可以了
我的按照第一个方式创建的组件是在窗口中心的,有的版本可能是和第二按钮一样在左上角,导致重合,不过都不要紧,反正位置可以调的 ,通过调用move函数移动按钮位置,以下是完整代码
#include "widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//创建一个按钮
QPushButton *bt1=new QPushButton; //这里要采用new的方式创建组件
bt1->show();//show()以顶层的方式弹出窗口控件
bt1->setParent(this);//因为在窗口类里创建的对象,所以用this指针就可以指向窗口
bt1->setText("我的第一个按钮");
//创建第二个按钮
QPushButton *bt2=new QPushButton("我的第二个按钮",this);
bt1->move(100,100);//移动第二个窗口
resize(640,400);//设置窗口大小
setFixedSize(640,400);//固定窗口大小,可以拖拽,不能缩放
setWindowTitle("我的第一个窗口");//设置窗口名称
}
Widget::~Widget()
{
}
总结:
- 创建按钮:QPushButton *bt1=new QPushButton;
- 设置父亲:setParent(this);
- 设置文本:setText(“文本”);
- 设置位置:move(宽,高);
- 重新指定窗口大小: resize
- 设置窗口标题:setwindowTitle
- 设置窗口固定大小:setFixedsize
在创建的组件是使用new的主要有两个原因,一就是非new在栈上,所以空间有限,能分配的空间相对小,再就是由于非new在栈上,所以会随着所在块的结束,也就是所在大括号{}之后会销毁,如果有局部自动变量,在退出构造函数之后这些自动变量就会被销毁,这样 你的窗口调用show的时候也不会显示组件了
我们通过new创建了两个按钮组件,但是在我们所写函数并没有添加相应的delete()函数,这主要是由于在QT中 对象树的概念,我们在创建按钮组件的时候把他父类指定了QWidget,而在QT中存在一个chidren表,两个按钮组件就放在chidren表中,当关闭窗口的时候QWidget析构的时候也会把在它chidren表中的控件析构
也就是如果在用new创建的对象指定的父类是QObject或者是QObject的子类对象是可以不用管理内存的释放的
四、信号和槽
简单使用
QT中的信号和槽机制可以简单的理解为:张三想要像李四表白,张三先在微信给李四发了表白消息,然后李四就拒绝了嘛
这里张三就是信号的发送者 在微信发的消息就是发送的信号,李四就是信号的接受者,李四拒绝就是处理的槽函数
现在实现点击按钮关闭窗口的实例
首先需要一个connect函数用来连接以上参数
//需求:点击我的第一个按钮关闭窗口
//参数1: 信号的发送者 参数二: 发送的信号(函数地址,这个函数地址可以理解成微信,就是要用哪种方式表白,这里就是用哪种组件的函数发送信号)
//参数3: 信号的接收者 参数4:处理的参函数
connect(bt1,&QPushButton::clicked,this,&Widget::close);//QPushButton发出点击的信号,Widget执行槽函数关闭窗口
QPushButton发出的信号可以在帮助文档中查询
Widget是继承于QWidget的,所以可以在帮助文档查找QWidget的槽函数
每个槽函数可以点击查看作用
自定义信号和槽
新创建一个文件夹SignalAndSlot
然后再用类似的方法创建一个Student类,我们这里定义teacher发送信号,student执行槽函数
实现功能:当下课了,老师饿了,学生请老师吃饭
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
//在这里写槽函数
//返回值是void,需要声明,也需要实现
//可以有参数,可以有重载
void treat();
};
#endif // STUDENT_H
teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号 写在signal下
//返回值是void,只需要声明,不需要实现
//可以有参数,可以重载
void hungry();
public slots:
};
#endif // TEACHER_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "teacher.h"
#include "student.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Teacher* zt;//定义类成员
Student* st;//定义类成员
Ui::Widget *ui;
void ClassIsOver();//定义下课了条件函数
};
#endif // WIDGET_H
student.cpp
#include "student.h"
#include <QDebug>//调试类
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat(){
qDebug()<<"on my treat today";//打印调试信息
}
teacher.cpp
#include "teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
//什么都不用写
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
//创建老师对象
this->zt =new Teacher(this);//把这个Teacher指定为Widget,放入对象树,就不用担心内存释放的问题
//创建学生对象
this->st =new Student(this);
//自定义的信号与槽
connect(zt,&Teacher::hungry,st,&Student::treat);
//添加下课了的前提
ClassIsOver(); //这个不能放在自定义信号于槽的语句前面,这里的逻辑是先有了信号了,然后条件达成触发信号
ui->setupUi(this);
}
void Widget::ClassIsOver(){
//下课了,老师饿了,触发信号
emit zt->hungry();
}
Widget::~Widget()
{
delete ui;
}
自定义信号和槽的重载情况
分别在teacher和student类中编写重载版本
在teacher.h中添加一句
void hungry(QString foodname);
student.h添加
void treat(QString foodname);
在student的cpp文件编写函数
void treat(QString foodname){
qDebug()<<"Reload version"<<foodname;
}
修改widget.cpp
重载版本的参数不能直接在connect中指定,要分别写两个函数的函数指针,通过函数指针访问
这里的food输出的带有双引号但是我们写的程序并没有添加双引号
qDebug()<<"Reload version"<<foodname;
这里通过强转,将QString转换成char* 类型就可以了
qDebug()<<"Reload version"<<foodname.toUtf8().data();
转换过程:先用toUTf8()转换成QByteArray,再把用data()把QByteArray转换成char*
信号连接信号
这个时候我们是一运行老师就饿了,然后输出了调试信息,现在添加一个按钮,当点击了按钮输出调试按钮
别忘记了添加头文件#include
现在就可以实现了点击按钮输出调试信息
接下来是通过信号连接信号的方式,创建两个按钮,按“有参调试”输出:Reload version food,按“无参调试”输出:on my treat today
widget.cpp完整代码
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
//创建老师对象
this->zt =new Teacher(this);//把这个Teacher指定为Widget,放入对象树,就不用担心内存释放的问题
//创建学生对象
this->st =new Student(this);
//自定义的信号与槽
//connect(zt,&Teacher::hungry,st,&Student::treat);
//连接带有参数的信号和槽
//函数指针->函数地址
void(Teacher:: *teacherSignal)(QString)=&Teacher::hungry;
void(Student:: *studentSlot)(QString)=&Student::treat;
connect(zt,teacherSignal,st,studentSlot);
QPushButton* bt1=new QPushButton("有参调试",this);
bt1->move(100,100);//移动按钮
connect(bt1,QPushButton::clicked,this,Widget::ClassIsOver);//当点击按钮,触发ClassISOver
//添加下课了的前提
//ClassIsOver(); //这个不能放在自定义信号于槽的语句前面,这里的逻辑是先有了信号了,然后条件达成触发信号
void(Teacher:: *teacherSignal2)(void)=&Teacher::hungry;//
void(Student:: *studentSlot2)(void)=&Student::treat;//先用函数指针指定使用的函数
connect(zt,teacherSignal2,st,studentSlot2);//创建信号与槽的连接
QPushButton* bt2=new QPushButton("无参调试",this);//创建按钮
bt2->move(100,200);//移动按钮
connect(bt2,QPushButton::clicked,zt,teacherSignal2); //信号连接信号
ui->setupUi(this);
}
void Widget::ClassIsOver(){
//下课了,老师饿了,触发信号
//emit zt->hungry();
emit zt->hungry("food");
}
Widget::~Widget()
{
delete ui;
}
在使用完一个信号连接后是可以断开的使用disconnect()断开连接,参数和要断开的连接一样
lambda表达式
在lambda表达式中实现一个信号对应多个槽
先创建一个按钮,实现在点击按钮的时候关闭窗口,并输出调试信息
//lamdba表达式
QPushButton* bt3=new QPushButton("lambda",this);
bt3->move(100,300);
connect(bt3,QPushButton::clicked,[=](){ //如果在使用lambda的时候如果第三个参数是this,可以省略不写
this->close();
this->ClassIsOver();
});
点击lambda会关闭窗口输出调试信息
五、QMainWindow
新建一个项目,选择QMainWindow,现在mainwindow.cpp添加以下头文件
#include "mainwindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QToolBar>
#include <QDebug>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
#include <QDockWidget>
#include <QTextEdit>
菜单栏
在QMainWindow类窗口中添加一个菜单栏,在MainWindow的构造函数添加以下两句即可显示出一个简单的菜单栏,最多只有一个
QMenuBar* bar = menuBar();//新建一个菜单,这里是不需要设置this指针的
setMenuBar(bar);//显示菜单栏
在菜单栏添加菜单
QMenu* fileMenu = bar->addMenu("file");//创建一个文件菜单
QMenu* newMenu = bar->addMenu("new");//创建一个新建菜单
QMenu* delMenu =bar->addMenu("del");//创建一个删除菜单
如果是在Window系统下添加之后不显示,检查一下是否创建了图形界面
菜单项
在菜单中的单个选项添加菜单项
fileMenu->addAction("last one");//创建文件下的一个菜单项
fileMenu->addSeparator(); //添加一跳分割线
fileMenu->addAction("before one");//创建文件下的一个菜单项
工具栏
添加一个工具栏
QToolBar* toolbar= new QToolBar(this);//这里还是要设置this指针
addToolBar(Qt::LeftToolBarArea,toolbar);//设置工具栏默认显示位置
这里使用的是addToolBar的一个重载函数,第一个参数可以设置为默认位置上下左右四个位置
创建完成不设置工具栏是可以随意拖动的,甚至可以拖动到窗口中间
设置一下浮动并让窗口只能停靠在左边或者右边
toolbar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);//设置只能显示在左边或者右边
toolbar->setFloatable(false);//设置浮动这样就可以使工具栏不显示在窗口中间
设置移动,设置之后工具栏就不可以移动了
toolbar->setMovable(false);
然后设置工具栏的内容
toolbar->addAction("tool1");
toolbar->addSeparator();
toolbar->addAction("tool2");
在工具栏添加一个按钮
toolbar->addSeparator();
QPushButton* bt = new QPushButton("tool3",this);
toolbar->addWidget(bt);
状态栏
跟菜单栏一样也只能有一个
设置一个状态栏
QStatusBar* stbar = new QStatusBar;//这里也是不用this,可以理解为由于只能设置一个QT已经帮我们设置好了
setStatusBar(stbar); //设置到窗口
添加控件标签
QLabel* lab1 = new QLabel("提示左侧信息",this);
stbar->addWidget(lab1);//在左侧显示一个标签
QLabel* lab2 = new QLabel("提示右侧信息",this);
stbar->addPermanentWidget(lab2);
设置浮动铆接部件
QDockWidget* dock1 = new QDockWidget("浮动",this);
addDockWidget(Qt::BottomDockWidgetArea,dock1);//第一个参数填设置位置,与工具栏类似
dock1->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); //设置只能在上下显示
这里设置的位置是下方
其他位置的设置可以参考帮助文档
在窗口内添加一个中心部件,中心部件也只能设置一个
QTextEdit* edi1 = new QTextEdit(this);
setCentralWidget(edi1);
这一节中有的控件是只能添加一个的,有的可以设置多个,可以根据使用对应的函数记忆,用set创建的就只能有一个,用add创建的就可以有多个
完整代码
#include "mainwindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QToolBar>
#include <QDebug>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
#include <QDockWidget>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(640,400);
QMenuBar* bar = menuBar();//新建一个菜单,这里是不需要设置this指针的
setMenuBar(bar);//显示菜单栏
QMenu* fileMenu = bar->addMenu("file");//创建一个文件菜单
QMenu* newMenu = bar->addMenu("new");//创建一个新建菜单
QMenu* delMenu =bar->addMenu("del");//创建一个删除菜单
//添加菜单项----------------------------------------------------------
fileMenu->addAction("last one");//创建文件下的一个菜单项
fileMenu->addSeparator(); //添加一跳分割线
fileMenu->addAction("before one");//创建文件下的一个菜单项
//添加工具栏----------------------------------------------------------
QToolBar* toolbar= new QToolBar(this);//这里还是要设置this指针
addToolBar(Qt::LeftToolBarArea,toolbar);//设置工具栏默认显示位置
toolbar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);//设置只能显示在左边或者右边
toolbar->setFloatable(false);//设置浮动这样就可以使工具栏不显示在窗口中间
//设置移动,设置之后工具栏就不可以移动了
toolbar->setMovable(false);
//设置工具栏内容
toolbar->addAction("tool1");
toolbar->addSeparator();
toolbar->addAction("tool2");
//在工具栏添加控件
toolbar->addSeparator();
QPushButton* bt = new QPushButton("tool3",this);
toolbar->addWidget(bt);
//添加状态栏---------------------------------------------------------
QStatusBar* stbar = new QStatusBar;//这里也是不用this,可以理解为由于只能设置一个QT已经帮我们设置hao
setStatusBar(stbar); //设置到窗口
//放标签控件
QLabel* lab1 = new QLabel("提示左侧信息",this);
stbar->addWidget(lab1);//在左侧显示一个标签
QLabel* lab2 = new QLabel("提示右侧信息",this);
stbar->addPermanentWidget(lab2);
//铆接部件(浮动窗口)
QDockWidget* dock1 = new QDockWidget("浮动",this);
addDockWidget(Qt::BottomDockWidgetArea,dock1);//第一个参数填设置位置,与工具栏类似
dock1->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); //设置只能在上下显示
//设置中心部件,只能一个
QTextEdit* edi1 = new QTextEdit(this);
setCentralWidget(edi1);
}
MainWindow::~MainWindow()
{
}
六、添加资源文件
新建一个项目My_Res,勾选图形界面创建
右击文件目录,选择在Explore中显示,跳转到文件目录,把要填加的资源文件放在目录下,这里以存放图片为例
然后右击项目根目录选择添加新文件
然后进入相应文件
然后点击编译
为菜单项添加图标
ui->actionedit->setIcon(QIcon(":/Image/Sunny.jpg"));
ui->actiondel->setIcon(QIcon(":/Image/Frame.jpg"));//这两句要放在ui->setupUi(this);的下面,不然运行不了的
七、对话框
新建一个项目My_QDig,先用图形界面创建以下界面
模态对话框
模态对话框:弹出后就不可以对其他窗口做操作
实现功能:点击tool,弹出一个模态对话框
connect(ui->actiontool,&QAction::triggered,[=](){//建立连接,当触发tool弹出窗口
//模态对话框------------------------------------------
QDialog dia1(this);//创建一个窗口
dia1.resize(520,300);//设置弹出的窗口大小
dia1.exec();//显示模态对话框
});
connect第二个参数是QAction里的信号
非模态对话框
非模态对话框:弹出后可以对其他的窗口操作
实现功能:点击tool2弹出一个非模态对话框
connect(ui->actiontool2,&QAction::triggered,[=](){//建立连接,当触发tool2弹出窗口
//非模态对话框----------------------------------------
//QDialog dia2(this);不能使用这种方式创建,这样创建窗口会一闪而过
QDialog *dia2 = new QDialog(this);//创建一个窗口,
dia2->resize(520,300);
dia2->setAttribute(Qt::WA_DeleteOnClose); //55号属性
dia2->show();//显示非模态对话框
});
}
QDialog dia2(this);不能使用这种方式创建,这样创建窗口会一闪而过,所以应该创建在堆区,由于模态对话框会有一个堵塞的特性,不会退出connect函数所以可以直接创建
dia2->setAttribute(Qt::WA_DeleteOnClose); ,由于创建在堆区,所以如果要是一直创建非模态对话框,在程序还在运行时内存是不会释放的,有可能引起内存泄漏,使用这句保证在每次创建的非模态对话框删除时清理内存
消息对话框
根据上述方法分别在菜单项的编辑添加模态对话框,删除添加非模态对话框
connect(ui->actionedit,&QAction::triggered,[=](){//建立连接,当触发编辑弹出窗口
//模态对话框------------------------------------------
QDialog dia3(this);//创建一个窗口
dia3.resize(520,300);//设置弹出的窗口大小
dia3.exec();//显示模态对话框
});
connect(ui->actiondel,&QAction::triggered,[=](){//建立连接,当触发删除弹出窗口
//非模态对话框----------------------------------------
QDialog *dia4 = new QDialog(this);//创建一个窗口,
dia4->resize(520,300);
dia4->setAttribute(Qt::WA_DeleteOnClose); //55号属性
dia4->show();//显示非模态对话框
});
实现功能:点击tool弹出错误消息,点击tool2弹出对话消息,点击编辑弹出提问消息,点击删除弹出警告信息
点击tool弹出错误消息:
connect(ui->actiontool,&QAction::triggered,[=](){//建立连接,当触发tool弹出窗口
//模态对话框------------------------------------------
//QDialog dia1(this);//创建一个窗口
//dia1.resize(520,300);//设置弹出的窗口大小
//dia1.exec();//显示模态对话框
QMessageBox::critical(this,"error","错误");//点击弹出错误信息
});
点击tool2弹出对话信息:
connect(ui->actiontool2,&QAction::triggered,[=](){//建立连接,当触发tool2弹出窗口
//非模态对话框----------------------------------------
//QDialog dia2(this);不能使用这种方式创建,这样创建窗口会一闪而过
//QDialog *dia2 = new QDialog(this);//创建一个窗口,
//dia2->resize(520,300);
//dia2->setAttribute(Qt::WA_DeleteOnClose); //55号属性
//dia2->show();//显示非模态对话框
QMessageBox::information(this,"info","Hello World");//点击弹出消息信息
});
点击编辑弹出提问消息:
connect(ui->actionedit,&QAction::triggered,[=](){//建立连接,当触发编辑弹出窗口
//模态对话框------------------------------------------
//QDialog dia3(this);//创建一个窗口
//dia3.resize(520,300);//设置弹出的窗口大小
//dia3.exec();//显示模态对话框
if(QMessageBox::Yes == QMessageBox::question(this,"edit","是否编辑",QMessageBox::Yes | QMessageBox::Yes,QMessageBox::No)){
qDebug()<<"开始编辑";QMessageBox::No
}else{
qDebug()<<"退出编辑";
}
});
点击yes弹出开始编辑消息,点击no弹出退出编辑消息
点击删除弹出警告信息:
connect(ui->actiondel,&QAction::triggered,[=](){//建立连接,当触发删除弹出窗口
//非模态对话框----------------------------------------
//QDialog *dia4 = new QDialog(this);//创建一个窗口,
//dia4->resize(520,300);
//dia4->setAttribute(Qt::WA_DeleteOnClose); //55号属性
//dia4->show();//显示非模态对话框
QMessageBox::warning(this,"warning","可能没有成功删除");
});
总结
QWidget* parent:指定父类
const QString &title:窗口标题
const QString &text: 窗口内容
StandardButton buttons:选择使用的按钮,这里只有question使用了这个
StandardButton defaultButton = NoButton:设置第四个窗口使用的默认值,比如上面的 question例子,默认值是
QMessageBox::No,也是就说如果不做选择直接回车会默认选择no运行
颜色对话框
实现功能:点击选择颜色,弹出颜色选择栏,选择后并输出调试信息
connect(ui->actioncolor,&QAction::triggered,[=](){//建立连接,当触发删除弹出窗口
//返回值是QColor而不是QcolorDialog
//QColor 参数一:red 参数二:green 参数三:blue 参数四:透明度
QColor color1 = QColorDialog::getColor(QColor(255,0,0,255));
qDebug() <<"r="<<color1.red()<<"g="<<color1.green()<<"b="<<color1.blue();
});
文件对话框
实现功能:点击选择文件,弹出指定的文件目录,并再选择文件后输出文件路径
connect(ui->actionfile,&QAction::triggered,[=](){
//返回值string,是打开文件的路径
//getOpenFileName 参数一:指定父亲 参数二:窗口名称 参数三:打开路径 参数四:筛选文件类型
QString cwd = QFileDialog::getOpenFileName(this,"打开桌面txt文件","E:/资源/桌面","*.txt");
qDebug() <<cwd;
});
字体对话框
实现功能:点击选择字体,弹出字体选择对话框,并输出选择后的字体信息
connect(ui->actionfont,&QAction::triggered,[=](){
bool flag;
//返回值是QFont而不是QFontDialog
//QFont 参数一:默认的字体 参数二:默认的大小
QFont font = QFontDialog::getFont(&flag,QFont("宋体",36));
qDebug()<<"字体:"<<font.family()<<"字号:"<<font.pointSize()<<"是否加粗"<<font.bold()<<"是否斜体"<<font.italic();
});
完整代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QMessageBox>
#include <QDebug>
#include <QColorDialog>
#include <QFileDialog>
#include <QFontDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(640,400);//设置主窗口大小
connect(ui->actiontool,&QAction::triggered,[=](){//建立连接,当触发tool弹出窗口
//模态对话框------------------------------------------
//QDialog dia1(this);//创建一个窗口
//dia1.resize(520,300);//设置弹出的窗口大小
//dia1.exec();//显示模态对话框
QMessageBox::critical(this,"error","错误");//点击弹出错误信息==============================消息对话框
});
connect(ui->actiontool2,&QAction::triggered,[=](){//建立连接,当触发tool2弹出窗口
//非模态对话框----------------------------------------
//QDialog dia2(this);不能使用这种方式创建,这样创建窗口会一闪而过
//QDialog *dia2 = new QDialog(this);//创建一个窗口,
//dia2->resize(520,300);
//dia2->setAttribute(Qt::WA_DeleteOnClose); //55号属性
//dia2->show();//显示非模态对话框
QMessageBox::information(this,"info","Hello World");//点击弹出消息信息====================消息对话框
});
connect(ui->actionedit,&QAction::triggered,[=](){//建立连接,当触发编辑弹出窗口
//模态对话框------------------------------------------
//QDialog dia3(this);//创建一个窗口
//dia3.resize(520,300);//设置弹出的窗口大小
//dia3.exec();//显示模态对话框
if(QMessageBox::Yes == QMessageBox::question(this,"edit","是否编辑",QMessageBox::Yes | QMessageBox::Yes,QMessageBox::No)){
qDebug()<<"开始编辑";
}else{
qDebug()<<"退出编辑";
}//=================================================================================消息对话框
});
connect(ui->actiondel,&QAction::triggered,[=](){//建立连接,当触发删除弹出窗口
//非模态对话框----------------------------------------
// QDialog *dia4 = new QDialog(this);//创建一个窗口,
// dia4->resize(520,300);
// dia4->setAttribute(Qt::WA_DeleteOnClose); //55号属性
// dia4->show();//显示非模态对话框
QMessageBox::warning(this,"warning","可能没有成功删除");//===============================消息对话框
});
//颜色对话框----------------------------------------------------------------------------
connect(ui->actioncolor,&QAction::triggered,[=](){//建立连接,当触发删除弹出窗口
//返回值是QColor而不是QcolorDialog
//QColor 参数一:red 参数二:green 参数三:blue 参数四:透明度 填参数是选择打开后的默认颜色
QColor color1 = QColorDialog::getColor(QColor(255,0,0,255));
qDebug() <<"r="<<color1.red()<<"g="<<color1.green()<<"b="<<color1.blue();
});
//文件对话框----------------------------------------------------------------------------
connect(ui->actionfile,&QAction::triggered,[=](){
QString cwd = QFileDialog::getOpenFileName(this,"打开桌面txt文件","E:/资源/桌面","*.txt");
qDebug() <<cwd;
});
//字体对话框----------------------------------------------------------------------------
connect(ui->actionfont,&QAction::triggered,[=](){
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("宋体",36));
qDebug()<<"字体:"<<font.family()<<"字号:"<<font.pointSize()<<"是否加粗"<<font.bold()<<"是否斜体"<<font.italic();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
八、自定义控件
QT里的各种已有的控件使用方法推荐观看视频