本文共 22488 字,大约阅读时间需要 74 分钟。
文章目录
1.Qt程序基本框架
创建项目
选择文件路径,编辑项目名称
选择编译器 选择基类,并修改继承类类名项目结构
- *.pro:项目配置文件
注意,项目配置文件中,使用
#
完成注释# 模块QT += core gui# 高于4版本,添加QT += widgets,为了兼容Qt4greaterThan(QT_MAJOR_VERSION, 4): QT += widgets# 应用程序的名字TARGET = 01day_qtTest# 指定makefile的类型,app,此外还有lib等类型TEMPLATE = appDEFINES += QT_DEPRECATED_WARNINGSCONFIG += c++11# 源文件SOURCES += \ main.cpp \ mainwindow.cpp# 头文件HEADERS += \ mainwindow.h# UI文件FORMS += \ mainwindow.ui# Default rules for deployment.qnx: target.path = /tmp/$${ TARGET}/binelse: unix:!android: target.path = /opt/$${ TARGET}/bin!isEmpty(target.path): INSTALLS += target
模块的添加,选中
类名
,按F1进入帮助文件查看类所述模块名称,并添加到配置文件。
Qt基本模块
- Qt Widgets:GUI最常用
- Qt Webkit:浏览器引擎
- Qt Test:测试单元
- Qt SQL:数据库
- Qt Quick、Qt QML、Qt Quick Controls、Qt Quick Dialogs:另外一个框架,主要用js实现
- Qt Mulitmedia Widgets、Qt Mulitmedia:多媒体
- Qt Network:网络
- Qt GUI、Qt Core:最基本的
2.第一个QT程序
创建一个空程序
main.cpp#include#include //窗口控件基类#include //按钮基类int main(int argc,char **argv){ QApplication app(argc,argv); QWidget w; w.show(); // 注意要人工显示才能显示 w.setWindowTitle("CSDN 牛B!"); //窗口标题 QPushButton b; b.setText("我是按钮~"); //设置按钮内容 b.show(); app.exec(); return 0;}
注意:创建控件后默认是隐藏的,需要人为显示!
指定父对象
① 如果不指定父对象,对象和对象(窗口和窗口)之间没有关系,是独立的!!!
② b指定a为它的父对象,相当于把b放在a的上面
指定父对象的2种方式:
- setParent
- 通过构造函数传参
指定父对象后,只需要父对象show,上面的子对象即可自动显示。
方式1:
#include#include //窗口控件基类#include //按钮基类int main(int argc,char **argv){ QApplication app(argc,argv); QWidget w; w.setWindowTitle(QString("CSDN 牛B!")); //窗口标题 QPushButton b; b.setText("我是按钮~"); //设置按钮内容 b.setParent(&w); w.show(); // 注意要人工显示才能显示 app.exec(); return 0;}
移动按钮位置
#include#include //窗口控件基类#include //按钮基类int main(int argc,char **argv){ QApplication app(argc,argv); QWidget w; w.setWindowTitle(QString("CSDN 牛B!")); //窗口标题 QPushButton b; b.setText("我是按钮~"); //设置按钮内容 b.setParent(&w);//指定父对象 b.move(100,100);//移动坐标 w.show(); // 注意要人工显示才能显示 app.exec(); return 0;}
左上角为坐标0点,左右为x轴,上下为y轴,以像素为单位。
方式2:
#include#include //窗口控件基类#include //按钮基类int main(int argc,char **argv){ QApplication app(argc,argv); QWidget w; w.setWindowTitle(QString("CSDN 牛B!")); //窗口标题 QPushButton b; b.setText("我是按钮~"); //设置按钮内容 b.setParent(&w);//指定父对象 b.move(100,100);//移动坐标 QPushButton b1(&w);//通过构造函数传参指定父对象 b1.setText("我是传参指定父类的按钮~"); w.show(); // 注意要人工显示才能显示 app.exec(); return 0;}
指针按钮
新建项目,基于Qwidget
mainwidget.h#ifndef MAINWIDGET_H#define MAINWIDGET_H#include#include class mainWidget : public QWidget{ Q_OBJECTpublic: mainWidget(QWidget *parent = 0); ~mainWidget();private: QPushButton b1; QPushButton *b2;};#endif // MAINWIDGET_H
main()
#include "mainwidget.h"#includeint main(int argc, char *argv[]){ QApplication a(argc, argv); mainWidget w;//执行MainWidget的构造函数 w.show(); return a.exec();}
mainwidget.cpp
#include "mainwidget.h"#includemainWidget::mainWidget(QWidget *parent) : QWidget(parent){ //QPushButton b; b1.setParent(this); b1.setText("^_^"); b1.move(100,100); b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存 b2->setText("我是指针按钮");}mainWidget::~mainWidget(){ }
3. 标准信号和槽
到目前为止,虽然创建了按钮,但是点击按钮无反应,这就需要信号和槽~
QT的核心在信号和槽,它是QT对象通信的接口!
标准信号和槽
#include "mainwidget.h"#includemainWidget::mainWidget(QWidget *parent) : QWidget(parent){ //QPushButton b; b1.setParent(this); b1.setText("close"); b1.move(100,100); b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存 b2->setText("我是指针按钮"); //槽函数不需要在类的头文件中声明 connect(&b1,&QPushButton::pressed,this,&mainWidget::close); /* &b1:信号发出者,指针类型 * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字 * this:信号接收者 * &mainWidget::close 槽函数,信号处理函数 &接收的类名::槽函数名 */}mainWidget::~mainWidget(){ }
自定义槽
注意,如果项目编译不是想要的结果,检查一下编译的是不是当前项目,尤其是多个项目并存的时候!
mainwidget.h
#ifndef MAINWIDGET_H#define MAINWIDGET_H#include#include class mainWidget : public QWidget{ Q_OBJECTpublic: mainWidget(QWidget *parent = 0); ~mainWidget(); void mySlot();//自定义槽函数private: QPushButton b1; QPushButton *b2;};#endif // MAINWIDGET_H
mainwidget.cpp
#include "mainwidget.h"#includemainWidget::mainWidget(QWidget *parent) : QWidget(parent){ //QPushButton b; b1.setParent(this); b1.setText("close"); b1.move(100,100); b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存 b2->setText("我是指针按钮"); connect(&b1,&QPushButton::pressed,this,&mainWidget::close); /* &b1:信号发出者,指针类型 * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字 * this:信号接收者 * &mainWidget::close 槽函数,信号处理函数 &接收的类名::槽函数名 */ /* 自定义槽,普通函数的用法 * Qt5:任意的成员函数,普通全局函数,静态函数 * 槽函数需要和信号一致(参数,返回值) * 由于信号都是没有返回值,所以槽函数一定没有返回值 */ connect(b2,&QPushButton::released,this,&mainWidget::mySlot); connect(b2,&QPushButton::released,&b1,&QPushButton::hide);//b2变身的同时,隐藏b1按钮}void mainWidget::mySlot(){ b2->setText("变身!");}mainWidget::~mainWidget(){ }
4. 两个独立的窗口
新建一个类subwidget
subwidget.h
#ifndef SUBWIDGET_H#define SUBWIDGET_H#include#include class subWidget : public QWidget{ Q_OBJECTpublic: explicit subWidget(QWidget *parent = nullptr);signals:public slots:private: QPushButton b;};#endif // SUBWIDGET_H
subwidget.cpp
#include "subwidget.h"subWidget::subWidget(QWidget *parent) : QWidget(parent){ this->setWindowTitle("子窗口"); b.setParent(this); b.setText("切换到主窗口"); b.move(100,100);}
mainwidget.h
#ifndef MAINWIDGET_H#define MAINWIDGET_H#include#include #include "subwidget.h"class mainWidget : public QWidget{ Q_OBJECTpublic: mainWidget(QWidget *parent = 0); ~mainWidget(); void mySlot();//自定义槽函数private: QPushButton b1; QPushButton *b2; QPushButton b3; subWidget w;};#endif // MAINWIDGET_H
mainwidget.cpp
#include "mainwidget.h"#includemainWidget::mainWidget(QWidget *parent) : QWidget(parent){ //QPushButton b; b1.setParent(this); b1.setText("close"); b1.move(100,100); b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存 b2->setText("我是指针按钮"); connect(&b1,&QPushButton::pressed,this,&mainWidget::close); /* &b1:信号发出者,指针类型 * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字 * this:信号接收者 * &mainWidget::close 槽函数,信号处理函数 &接收的类名::槽函数名 */ /* 自定义槽,普通函数的用法 * Qt5:任意的成员函数,普通全局函数,静态函数 * 槽函数需要和信号一致(参数,返回值) * 由于信号都是没有返回值,所以槽函数一定没有返回值 */ connect(b2,&QPushButton::released,this,&mainWidget::mySlot); connect(b2,&QPushButton::released,&b1,&QPushButton::hide);//b2变身的同时,隐藏b1按钮 b3.setParent(this); b3.move(300,100); b3.setText("切换到子窗口"); w.show();}void mainWidget::mySlot(){ b2->setText("变身!");}mainWidget::~mainWidget(){ }
main.cpp
#include "mainwidget.h"#includeint main(int argc, char *argv[]){ QApplication a(argc, argv); mainWidget w;//执行MainWidget的构造函数 w.show(); return a.exec();}
自定义信号
subwidget.h
#ifndef SUBWIDGET_H#define SUBWIDGET_H#include#include class subWidget : public QWidget{ Q_OBJECTpublic: explicit subWidget(QWidget *parent = nullptr); void sendSlot();signals: /* 信号由signals关键字声明 * 信号没有返回值,但可有参数 * 信号就是函数的声明,只需声明,无需定义 * 使用:emit mySignal(); */ void mySignal();public slots:private: QPushButton b;};#endif // SUBWIDGET_H
subwidget.cpp
#include "subwidget.h"subWidget::subWidget(QWidget *parent) : QWidget(parent){ this->setWindowTitle("子窗口"); b.setParent(this); b.setText("切换到主窗口"); b.move(100,100); resize(400,300);//设置窗口大小 connect(&b,&QPushButton::clicked,this,&subWidget::sendSlot);}void subWidget::sendSlot(){ emit mySignal();}
mainwidget.h
#ifndef MAINWIDGET_H#define MAINWIDGET_H#include#include #include "subwidget.h"class mainWidget : public QWidget{ Q_OBJECTpublic: mainWidget(QWidget *parent = 0); ~mainWidget(); void mySlot();//自定义槽函数 void changeWidget();// void dealSub();private: QPushButton b1; QPushButton *b2; QPushButton b3; subWidget sub;};#endif // MAINWIDGET_H
mainwidget.cpp
#include "mainwidget.h"#includemainWidget::mainWidget(QWidget *parent) : QWidget(parent){ //QPushButton b; b1.setParent(this); b1.setText("close"); b1.move(100,100); b2 = new QPushButton(this);//注意,指针是空的,应该先分配内存 b2->setText("我是指针按钮"); connect(&b1,&QPushButton::pressed,this,&mainWidget::close); /* &b1:信号发出者,指针类型 * &QPushButton::pressed 处理的信号, &发送者的类名::信号名字 * this:信号接收者 * &mainWidget::close 槽函数,信号处理函数 &接收的类名::槽函数名 */ /* 自定义槽,普通函数的用法 * Qt5:任意的成员函数,普通全局函数,静态函数 * 槽函数需要和信号一致(参数,返回值) * 由于信号都是没有返回值,所以槽函数一定没有返回值 */ connect(b2,&QPushButton::released,this,&mainWidget::mySlot); connect(b2,&QPushButton::released,&b1,&QPushButton::hide);//b2变身的同时,隐藏b1按钮 b3.setParent(this); b3.move(300,100); b3.setText("切换到子窗口"); //sub.show();//显示子窗口 connect(&b3,&QPushButton::released,this,&mainWidget::changeWidget); //处理子窗口的信号 connect(&sub,&subWidget::mySignal,this,&mainWidget::dealSub); resize(400,300);//设置窗口大小}void mainWidget::mySlot(){ b2->setText("变身!");}void mainWidget::changeWidget(){ //子窗口显示 //本窗口隐藏 sub.show(); this->hide();}void mainWidget::dealSub(){ sub.hide(); this->show();}mainWidget::~mainWidget(){ }
不同窗口之间信号的通信: ① 子窗口类中定义信号,使用signals
关键字定义信号函数void mySignal()
,信号没有返回值,但可有参数,信号就是函数的声明,只需声明,无需定义; ② 定义信号发送函数void sendSlot()
,使用connect
连接控件与信号发送之间的关系:connect(&控件对象,&信号类型,this,&信号发送函数;
信号发送函数定义为:
void subWidget::sendSlot(){ emit mySignal();}
使用emit
来关联信号类型
void dealSub()
,并使用connect
将子窗口的信号与操作关联起来,connect(&子窗口类对象,&子窗口中定义的信号,this,&处理子窗口信号的具体操作函数);
带参数的信号
信号可以重载
subwidget.hsignals: /* 信号由signals关键字声明 * 信号没有返回值,但可有参数 * 信号就是函数的声明,只需声明,无需定义 * 使用:emit mySignal(); * 信号可以重载 */ void mySignal(); void mySignal(int,QString);
subwidget.cpp
void subWidget::sendSlot(){ emit mySignal(); emit mySignal(250,"我是子窗口");}
注意注意:信号重载后,链接函数connect
会出现二义性,这时候需要用函数指针来处理!
//处理子窗口的信号 void (subWidget::*funSignal)() = &subWidget::mySignal; connect(&sub,funSignal,this,&mainWidget::dealSub); void (subWidget::*testSignal)(int,QString) = &subWidget::mySignal; connect(&sub,testSignal,this,&mainWidget::dealSlot);void mainWidget::dealSlot(int a, QString str){ // str.toUtf8() -> 字节数组QByteArray // ……data() -> QByteArray -> char * qDebug() << a << str.toUtf8().data();}
另外一种简单方法:
但是注意,只要是简单方法,都可能容易出问题!
SIGNAL SLOT 将函数名称直接转换为字符串,而不进行错误检查
在Qt4中,可以这样写:
mainwidget.cpp//Qt4信号连接 //Qt4槽函数必须有slots关键字 connect(&sub,SIGNAL(mySignal()),this,SLOT(dealSub())); connect(&sub,SIGNAL(mySignal(int,QString)), this,SLOT(dealSlot(int,QString)));
mainwidget.h
class mainWidget : public QWidget{ Q_OBJECTpublic: mainWidget(QWidget *parent = 0); ~mainWidget();/public slots: void mySlot();//自定义槽函数 void changeWidget();// void dealSub(); void dealSlot(int,QString);/private: QPushButton b1; QPushButton *b2; QPushButton b3; subWidget sub;};
大型项目中建议使用QT5中的语法!
Lamda表达式和再说信号的功能
C++增加的新特性,项目文件中添加CONFIG += C++11
,Qt配合信号一起使用非常方便。
mainwidget.cpp中
//Lambda表达式,匿名函数对象 //C++11增加的新特性,项目文件:CONFIG += c++11 //Qt配合信号一起使用,非常方便 QPushButton *b4 = new QPushButton(this); b4->setText("Lambda表达式"); b4->move(200,200); connect(b4,&QPushButton::released, [b4]()//方括号[]是用来传参的 { b4->setText("123"); qDebug() << "111111"; } );
如果这样写,[=]()
,这会把外部所有局部变量、类中所有成员以值传递方式传递进来,此时是不能修改变量值的。
int a=10,b=20; connect(b4,&QPushButton::released, // = :把外部所有局部变量、类中所有成员以值传递方式传递进来 [=]()//方括号[]是用来传参的 { b4->setText("123"); qDebug() << "111111"; qDebug() << a << b; } );
如果想修改值的大小,这样写:
int a=10,b=20; connect(b4,&QPushButton::released, // = 把外部所有局部变量、类中所有成员以值传递方式传递进来 //this 把类中所有成员以值传递方式传进来 // & 把外部所有局部变量,引用方式,使用引用时,对象不能用指针类型 [=]() mutable//方括号[]是用来传参的 { b4->setText("123"); qDebug() << "111111"; qDebug() << a << b; a = 11; } );
错误示范:使用引用方式传参,传指针对象时
connect(b4,&QPushButton::released, // = 把外部所有局部变量、类中所有成员以值传递方式传递进来 //this 把类中所有成员以值传递方式传进来 // & 把外部所有局部变量,引用方式,使用引用时,对象不能用指针类型 [&]() mutable//方括号[]是用来传参的 { b4->setText("123");//问题在这儿 qDebug() << "111111"; qDebug() << a << b; a = 11; } );
D:\Program Files (x86)\SogouInput\Components 12:42:09: The program has unexpectedly finished. 12:42:09: The process was ended forcefully. 12:42:09: G:/xxxx/qtProjects/build-01day_03_SignalAndSlot-Desktop_Qt_5_12_1_MinGW_64_bit-Debug/debug/01day_03_SignalAndSlot.exe crashed.
窗口直接崩掉把b4->setText("123");
屏蔽掉:
此处不知道问题出在哪儿,有了解的大佬还请留言指教!
小结:最安全的方法还是[=]()
这种
connect(b4,&QPushButton::clicked, [=](bool isCheck) { qDebug() << isCheck; } );
5. 坐标系统
#include "mywidget.h"#includeMyWidget::MyWidget(QWidget *parent) : QWidget(parent){ /* 对于父窗口,坐标系相对于屏幕 * 原点:相对于屏幕左上角 * x:往右递增 * y:往下递增 */ move(750,300); QPushButton *b1 = new QPushButton(this); b1->setText("^_^"); /* 对于子窗口,坐标系相对于父窗口 * 原点:相对于父窗口左上角 * x:往右递增 * y:往下递增 */ b1->move(0,0); b1->resize(200,200);//设置按钮大小 QPushButton *b2 = new QPushButton(b1); /* 对于子控件,坐标系相对于父控件 * 原点:相对于父控件左上角 * x:往右递增 * y:往下递增 */ b2->move(50,50); b2->setText("@_@");}MyWidget::~MyWidget(){ }
简单一句话:左上角为0点,x正为→,y正为↓
6. 内存回收机制
动态分配空间,如果不做处理,可能会造成内存泄露的问题。Qt中自动实现内存回收,但有两个条件:①指定父对象后;②直接或间接继承与QObject
。这时,如果子对象是动态分配空间(new
),不需要手动释放(delete
),系统会自动释放。
#ifndef MYBUTTON_H#define MYBUTTON_H#include#include class myButton : public QPushButton{ Q_OBJECTpublic: explicit myButton(QWidget *parent = nullptr); ~myButton();signals:public slots:};#endif // MYBUTTON_H
mybutton.cpp
#include "mybutton.h"#includemyButton::myButton(QWidget *parent) : QPushButton(parent){ }myButton::~myButton(){ qDebug() << "按钮被析构";}
mywidget.h
#ifndef MYWIDGET_H#define MYWIDGET_H#includeclass MyWidget : public QWidget{ Q_OBJECTpublic: MyWidget(QWidget *parent = 0); ~MyWidget();};#endif // MYWIDGET_H
mywidget.cpp
#include "mywidget.h"#include#include "mybutton.h"MyWidget::MyWidget(QWidget *parent) : QWidget(parent){ /* 对于父窗口,坐标系相对于屏幕 * 原点:相对于屏幕左上角 * x:往右递增 * y:往下递增 */ move(750,300); QPushButton *b1 = new QPushButton(this); b1->setText("^_^"); /* 对于子窗口,坐标系相对于父窗口 * 原点:相对于父窗口左上角 * x:往右递增 * y:往下递增 */ b1->move(0,0); b1->resize(200,200);//设置按钮大小 QPushButton *b2 = new QPushButton(b1); /* 对于子控件,坐标系相对于父控件 * 原点:相对于父控件左上角 * x:往右递增 * y:往下递增 */ b2->move(50,50); b2->setText("@_@"); myButton *b3 = new myButton(this); b3->setText("析构测试按钮");}MyWidget::~MyWidget(){ }
当主窗口关闭,
myButton
的析构函数将被调用。
7. 创建一个MainWindow
菜单栏-工具栏
mainwindow.cpp#include "mainwindow.h"#include#include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ //菜单栏 QMenuBar *mBar = menuBar(); //添加菜单 QMenu *pFile = mBar->addMenu("文件"); //添加菜单项,添加动作 QAction *pNew = pFile->addAction("新建"); connect(pNew,&QAction::triggered, [=]() { qDebug()<<"新建按键被按下"; } ); pFile->addSeparator();//添加分割线 QAction *pOpen = pFile->addAction("打开"); //工具栏,菜单栏的快捷方式 QToolBar *toolBar = addToolBar("toolBar"); //工具栏添加快捷键 toolBar->addAction(pNew); QPushButton *b = new QPushButton(this); b->setText("^_^"); //添加小控件 toolBar->addWidget(b); connect(b,&QPushButton::clicked, [=]() { b->setText("123"); } ); //状态栏 //核心控件 //浮动窗口}MainWindow::~MainWindow(){ }
状态栏
mainwindow.cpp#include "mainwindow.h"#include#include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ //菜单栏 QMenuBar *mBar = menuBar(); //添加菜单 QMenu *pFile = mBar->addMenu("文件"); //添加菜单项,添加动作 QAction *pNew = pFile->addAction("新建"); connect(pNew,&QAction::triggered, [=]() { qDebug()<<"新建按键被按下"; } ); pFile->addSeparator();//添加分割线 QAction *pOpen = pFile->addAction("打开"); //工具栏,菜单栏的快捷方式 QToolBar *toolBar = addToolBar("toolBar"); //工具栏添加快捷键 toolBar->addAction(pNew); QPushButton *b = new QPushButton(this); b->setText("^_^"); //添加小控件 toolBar->addWidget(b); connect(b,&QPushButton::clicked, [=]() { b->setText("=_="); } ); //状态栏 QStatusBar *sBar = statusBar(); QLabel *label = new QLabel(this); label->setText("Normal text file"); sBar->addWidget(label); //addWidget 从左往右添加 sBar->addWidget(new QLabel("2",this)); //addPermanentWidget 从右往左添加 sBar->addPermanentWidget(new QLabel("3",this)); //核心控件 //浮动窗口}MainWindow::~MainWindow(){ }
核心控件和浮动窗口
- 核心控件
#include "mainwindow.h"#include#include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ //菜单栏 QMenuBar *mBar = menuBar(); //添加菜单 QMenu *pFile = mBar->addMenu("文件"); //添加菜单项,添加动作 QAction *pNew = pFile->addAction("新建"); connect(pNew,&QAction::triggered, [=]() { qDebug()<<"新建按键被按下"; } ); pFile->addSeparator();//添加分割线 QAction *pOpen = pFile->addAction("打开"); //工具栏,菜单栏的快捷方式 QToolBar *toolBar = addToolBar("toolBar"); //工具栏添加快捷键 toolBar->addAction(pNew); QPushButton *b = new QPushButton(this); b->setText("^_^"); //添加小控件 toolBar->addWidget(b); connect(b,&QPushButton::clicked, [=]() { b->setText("=_="); } ); //状态栏 QStatusBar *sBar = statusBar(); QLabel *label = new QLabel(this); label->setText("Normal text file"); sBar->addWidget(label); //addWidget 从左往右添加 sBar->addWidget(new QLabel("2",this)); //addPermanentWidget 从右往左添加 sBar->addPermanentWidget(new QLabel("3",this)); //核心控件 QTextEdit *textEdit = new QTextEdit(this); setCentralWidget(textEdit); //浮动窗口}MainWindow::~MainWindow(){ }
- 浮动窗口
#include "mainwindow.h"#include#include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ //菜单栏 QMenuBar *mBar = menuBar(); //添加菜单 QMenu *pFile = mBar->addMenu("文件"); //添加菜单项,添加动作 QAction *pNew = pFile->addAction("新建"); connect(pNew,&QAction::triggered, [=]() { qDebug()<<"新建按键被按下"; } ); pFile->addSeparator();//添加分割线 QAction *pOpen = pFile->addAction("打开"); //工具栏,菜单栏的快捷方式 QToolBar *toolBar = addToolBar("toolBar"); //工具栏添加快捷键 toolBar->addAction(pNew); QPushButton *b = new QPushButton(this); b->setText("^_^"); //添加小控件 toolBar->addWidget(b); connect(b,&QPushButton::clicked, [=]() { b->setText("=_="); } ); //状态栏 QStatusBar *sBar = statusBar(); QLabel *label = new QLabel(this); label->setText("Normal text file"); sBar->addWidget(label); //addWidget 从左往右添加 sBar->addWidget(new QLabel("2",this)); //addPermanentWidget 从右往左添加 sBar->addPermanentWidget(new QLabel("3",this)); //核心控件 QTextEdit *textEdit = new QTextEdit(this); setCentralWidget(textEdit); //浮动窗口 QDockWidget *dock = new QDockWidget(this); addDockWidget(Qt::RightDockWidgetArea,dock); //给浮动窗口添加一个文本框 QTextEdit *textEdit1 = new QTextEdit(this); dock->setWidget(textEdit1);}MainWindow::~MainWindow(){ }
小技巧:接口开头不是
add
就是set
对话框
模态和非模态对话框
- 模态对话框:操作时只能操作当前对话框
- 非模态对话框:操作当前对话框时,可同时操作其他对话框 新建项目
01day_06_Dialog
,先以QMaiinWindow
为基类: mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include#include class MainWindow : public QMainWindow{ Q_OBJECTpublic: MainWindow(QWidget *parent = 0); ~MainWindow(); QDialog dlg;};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"#include#include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ QMenuBar *mBar = menuBar(); setMenuBar(mBar); QMenu *menu = mBar->addMenu("对话框"); QAction *p1 = menu->addAction("模态对话框"); connect(p1,&QAction::triggered, [=]() { QDialog dlg; dlg.exec();//等待用户操作 qDebug()<<"111111111111";//操作完会打印这句话 }); QAction *p2 = menu->addAction("非模态对话框"); connect(p2,&QAction::triggered, [=]() { //QDialog dlg;//此种情况,运行后对话框由于没有等待用户操作,将会直接闪退,此时可将其当做类成员 // 实现方式1:最简单// dlg.show();// qDebug()<<"22222222"; //实现方式2:// QDialog *p = new QDialog(this);// p->show();//这种方式只有在关闭时才会释放,这就导致内部越用越少 //实现方式3: QDialog *p = new QDialog; p->setAttribute(Qt::WA_DeleteOnClose);//关闭即释放 p->show(); });}MainWindow::~MainWindow(){ }
对于非模态对话框,有三种实现方式:
-
方式1:最简单
//QDialog dlg;作为类成员dlg.show();
-
方式2:可能会导致内存泄露
QDialog *p = new QDialog(this);p->show();//这种方式只有在关闭时才会释放,这就导致内部越用越少
-
方式3
QDialog *p = new QDialog;p->setAttribute(Qt::WA_DeleteOnClose);//关闭即释放p->show();
标准对话框和文件对话框
- 标准对话框
QAction *p3 = menu->addAction("关于对话框"); connect(p3,&QAction::triggered, [=]() { QMessageBox::about(this,"about","关于qt"); } ); QAction *p4 = menu->addAction("问题对话框"); connect(p4,&QAction::triggered, [=]() { int ret = QMessageBox::question(this,"question","are you ok?", QMessageBox::Ok,QMessageBox::Cancel); switch (ret) { case QMessageBox::Ok: qDebug()<<"I am ok"; break; case QMessageBox::Cancel: qDebug()<<"I am bad"; break; default: break; } } );
- 文件对话框
QAction *p5 = menu->addAction("文件对话框"); connect(p5,&QAction::triggered, [=]() { QString path = QFileDialog::getOpenFileName( this, "open", "../",//路径设置 "souce(*.cpp *.h);;Text(*.txt);;all(*.*)");//过滤器,可自动换行 qDebug() <
转载地址:https://miracle.blog.csdn.net/article/details/105842231 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!