Qt学习第1天:基本操作(信号与槽等) 【笔记】
发布日期:2021-07-01 04:00:39 浏览次数:2 分类:技术文章

本文共 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种方式:

  1. setParent
  2. 通过构造函数传参

指定父对象后,只需要父对象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"#include 
int main(int argc, char *argv[]){
QApplication a(argc, argv); mainWidget w;//执行MainWidget的构造函数 w.show(); return a.exec();}

mainwidget.cpp

#include "mainwidget.h"#include 
mainWidget::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"#include 
mainWidget::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"#include 
mainWidget::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"#include 
mainWidget::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"#include 
int 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"#include 
mainWidget::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.h

signals:    /* 信号由signals关键字声明     * 信号没有返回值,但可有参数     * 信号就是函数的声明,只需声明,无需定义     * 使用:emit mySignal();     * 信号可以重载     */    void mySignal();    void mySignal(int,QString);

subwidget.cpp

void subWidget::sendSlot(){
emit mySignal(); emit mySignal(250,"我是子窗口");}

注意注意:信号重载后,链接函数connect会出现二义性,这时候需要用函数指针来处理!

mainwidget.cpp

//处理子窗口的信号    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"#include 
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("@_@");}MyWidget::~MyWidget(){
}

简单一句话:左上角为0点,x正为→,y正为↓

6. 内存回收机制

动态分配空间,如果不做处理,可能会造成内存泄露的问题。Qt中自动实现内存回收,但有两个条件:①指定父对象后;②直接或间接继承与QObject这时,如果子对象是动态分配空间(new),不需要手动释放(delete),系统会自动释放。

例程:
mybutton.h

#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"#include 
myButton::myButton(QWidget *parent) : QPushButton(parent){
}myButton::~myButton(){
qDebug() << "按钮被析构";}

mywidget.h

#ifndef MYWIDGET_H#define MYWIDGET_H#include 
class 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(){ }

核心控件和浮动窗口

  1. 核心控件
    在这里插入图片描述
#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(){ }
  1. 浮动窗口

在这里插入图片描述

mainwindow.cpp

#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();
标准对话框和文件对话框
  1. 标准对话框
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; } } );
  1. 文件对话框
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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Qt学习第2天:常用控件与事件 【笔记】
下一篇:运动学系列 —— 几种雅克比矩阵的区别及RBT中的代码对比

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月18日 13时26分14秒