Qt教程

本文概述了Qt GUI编程的基础,包括初始化程序、创建按钮、信号槽连接、自定义槽、菜单栏、对话框(模态与非模态)、文件对话框及Lambda的使用。深入理解并实践这些内容,将有助于你高效地设计和响应GUI界面。
摘要由CSDN通过智能技术生成

基本介绍

以下是介绍初始化代码的含义,如果做一个项目,新建一个空项目开始写。

初始程序

新建Application (Qt) 项目,初始main.cpp文件代码如下:

#include <QApplication>
int main(int argc, char *argv[]){
  QApplication a(argc, argv);
  //只有一个应用程序
  
  MyWidget w;
  //MyWidget继承于QWidget,是一个窗口基类,w是一个窗口
  
  w.show();
  //窗口默认隐藏,需要人为显示
  
  a.exec();
  //一直显示界面

  return 0;
  //最后两行也可以写成return a.exec();
}

.pro文件说明如下

QT	+= core gui  #模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets #为了兼容QT4

TARGET # 应用程序的名字(标题)
TEMPLATE = app # 指定makefile的类型(可能没有)

SOURCES += main.cpp\
  		   mywidget.cpp
  		   
HEADERS += mywidget.h
CONFIG += C++11  #表示支持C++11标准

创建一个myWidget.cpp文件,代码如下:

#include <QWidget>
class MyWidget : public QWidget{
public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();
}

创建按钮

按钮的相关API如下代码所示,在main.cpp中包含头文件

#include <QPushButton> //在main.cpp中包含头文件
QPushButton b; //创建对象
b.setParent(&w); //指定父对象
b.move(num1, num2); //移动按钮,num1和num2分别为x和y坐标
b.setText(“buttonName”); //设置按钮名称

创建按钮时需要把指定按钮的父对象,不指定的话表现为按钮和主窗口是独立的

指定父对象有两种方式:

  • setParent

    b.setParent(&w);

    setParent函数参数为指针类型

  • 通过构造函数传参

    b = new QPushButton(this);

也可以直接在myWidget.h文件中创建按钮
在MyWidget类的私有成员中添加:

QPushButton b1;
QPushButton *b2;

myWidget.cpp文件中,在类的构造函数中定义,其中b1和b2编写方式有所不同:

b1.setParent(this);
b1.setText("ButtonName1");

b2 = new QPushButton(this);
b2->setText("ButtonName2");

信号和槽

信号(signal)就是在特定情况下被发射的事件,比如PushButton常见信号是单击鼠标时发射的clicked()信号
槽(slot)就是对信号响应的函数。与一般C++函数一样,可定义在类的任意部分(public \ private),可以具有任何参数也可以被直接调用。不同的是,槽函数可以与一个信号关联,信号被发射时,关联的槽函数自动执行。

GUI程序设计的主要内容就是对界面上各组件的信号的响应,信号与槽机制是 Qt GUI 编程的基础,使用信号与槽机制可以比较容易地将信号与响应代码关联起来。
在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT。

信号和槽连接函数

信号和槽关联是用QObject::connect()函数实现,基本格式为

connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

connect函数参数解释:

  • sender是发射信号的对象名称(指针类型)
  • signal()是信号名称。信号可看作特殊函数,需要带括号,有参数需指明参数。
    &发射者的类名::信号名
  • receiver是接收信号的对象名称
  • slot()是槽函数名称(信号处理函数)。
    &接收者类名::槽函数名

比如上述代码中,单击b1按钮执行关闭界面功能:

connect(&b1, &QPushButton::clicked, this, &MyWidget::close);

将 btnClose 按钮的 clicked() 信号与窗体(Widget)的槽函数 close() 相关联,当单击 btnClose 按钮(就是界面上的“Close”按钮)时,就会执行 Widget 的 close() 槽函数。

信号和槽连接规则

一个信号可以连接多个槽,多个信号可以连接同一个槽,一个信号可以连接另外一个信号

  • 一个信号可以连接多个槽:
    sender对象发射信号时,其连接的多个槽按建立连接的顺序依次执行
  • 多个信号可以连接同一个槽
    任一sender对象发射信号,都会执行槽函数
  • 一个信号可以连接另外一个信号
    一个信号发射时,也会发射另一信号

自定义槽

槽函数可以是任意的成员函数,普通全局函数,静态函数
槽函数需要和信号一致(参数,返回值)。由于信号没有返回值,所以槽函数一定没有返回值
信号可以带参数,因此可以重载,连接时需要定义函数指针来指明。
信号用signals关键字修饰之后,可以用宏SIGNAL查找,相应地,槽可以用slots修饰,用宏SLOT查找。(QT4)(尽量少使用)
注意,宏查找会将函数名字用字符串替换,不进行错误检查,可能会引发错误

切换窗口

首先在项目中创建一个新类subWindow,在主窗口的私有成员中创建类对象

SubWindow sw;

先在公有成员中定义一个切换窗口和处理子类对象发射信号的函数(切换回主窗口)

void showSub(); //隐藏主窗口,显示子窗口
void showMain(); //隐藏子窗口,显示主窗口

在类中的signals模块中定义信号函数
信号必须有signals关键字来声明,没有返回值,可以有参数

signals: void changeWindow();

设置一个切换窗口的按钮sw1,将sw1的点击事件与函数sendChangeWindowSlot()连接,自定义函数中发射信号:

emit changeWindow();

在主窗口的类myWidget中增加一条连接,连接子窗口发射的信号名changeWindow与showMain()函数。

Lambda

Lambda是C++11新特性,这部分介绍怎么把QT和Lambda结合使用
在自定义槽函数过程中,单击某一按钮发射信号,都需要在主类中定义槽函数,并用connect()函数连接,而使用Lambda可以这样写:

b3 = new QPushButton(this);
b3->setText("print")
connect()b3, &QPushButton::clicked, [](){
        qDebug() << "Hello";
    }
);

如果想在lambda函数体中使用b3,需要在方括号中传入参数b3,即

connect()b3, &QPushButton::clicked, [b3](){
        b3->setText("changed")  //如果方括号不加b3参数,该行编译错误(捕获不到)
        qDebug() << "Hello";
    }
);

方括号里加等号"[=]",表示把外部所有局部变量、类中所有成员以值传递方式传入函数,默认只读,如果需要修改,加mutable修饰

[=]() mutable {

}

菜单栏

如代码所示,一般window应用程序要添加的控件示例

#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QToolBar>
#include <QStatusBar>
#include <QLabel>
#include <QPushButton>
#include <QTextEdit>
#include <QDockWidget>

...{
    QMenuBar * mBar = menuBar();  //菜单栏
    
    //添加菜单
    QMenu *pFile = mBar->addMenu("文件");
    QMenu *pEdit = mBar->addMenu("编辑");
    QMenu *pTool = mBar->addMenu("工具");
    QMenu *pHelp = mBar->addMenu("帮助");
    
    //添加菜单项/动作
    QAction *pNew = pFile->addAction("新建");
    QAction *pOpen = pFile->addAction("打开");

    pFile->addSeparator(); //添加分割线

    //添加按钮小控件
    QPushButton *b = new QPushButton(this);
    b->setText("Save");
    toolBar->addWidget(b);
    
    //状态栏
    QStatusBar *stBar = statusBar();
    QLabel *label = new QLabel(this);
    label->setText("Normal Text File");
    statusBar->addWidget(label);
    
    //核心控件:文本编辑区
    QTextEdit *txEdit = new QTextEdit(this);
    setCentralWidget(textEdit);
    
    //浮动窗口
    QDockWidget *dock = new QDockWidget(this);
    addDockWidget(Qt::RightDockWidgetArea, dock);
    

}

对话框

对话框(Dialog)分为模态对话框和非模态对话框,常用的是标准对话框和文件对话框

模态和非模态

  • 模态对话框要求用户只能处理当前对话框,不能选中其他对话框
  • 非模态对话框允许用户处理其他对话框
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QDialog>
...{
    QMenuBar *mar = menuBar();
    setMenuBar(mBar);
    QMenu *menu = mBar->addMenu("对话框");
    QAction *p1 = menu->addAction("模态对话框")
    connect(p1, &QAction::triggered,
        [=](){
            QDialog dlg;  
            dlg.exec();//模态对话框
            //dlg.show();  //非模态对话框
        }
    );
}

运行完connect函数体,非模态对话框会消失,因此需要在主类中创建对话框对象
或者在函数体中动态创建,但是要注意释放,否则内存越用越少。可以设置对话框属性来实现:

p->setAttribute(Qt::WA DeleteOnClose);

标准对话框

标准对话框需要包含头文件#include <QMessageBox>

#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QDialog>
#include <QMessageBox>
...{
    ...
    QAction *p2 = menu->addAction("标准对话框")
    connect(p2, &QAction::triggered,
        [=](){
            QMessageBox::about(this, "Title", "Context");
        }
    );
    QAction *p3 = menu->addAction("问题对话框")
    connect(p3, &QAction::triggered,
        [=](){
            int ret = QMessageBox::question(this, "Title", "Yes or No?", 
              QMessageBox::Ok | QMessageBox::Cancle);
            swtich(ret){
                case QMessageBox::Ok: ... break;
                case QMessageBox::Cancle: ... break;
                default: break;
            }
        }
    );
}

文件对话框

打开一个文件的对话框

#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QDialog>
#include <QMessageBox>
#include <QFileDialog>
...{
    ...
    QAction *p4 = menu->addAction("文件对话框")
    connect(p4, &QAction::triggered,
        [=](){
            QString path = QFileDialog::getOpenFileName(
                           this,
                            "Title", 
                            "Path",
                            "source(*.cpp *.h);;Text(*.txt);;all(*.*)"
                            //指定格式
                            );
        }
    );
    
}

其他

光标指定某一对象,按F1可跳至帮助文档
QT中输入输出:

#include <QDebug>

可以把qDebug()当作C++中的cout来使用,比如

qDebug() << str.toUtf8().data();

QString类型的str直接打印不能正确输出,必须使用上述的代码转换成utf8格式之后再输出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值