Qt基础入门指南
Qt是一个功能强大的跨平台C++图形用户界面应用程序开发框架。在学习Qt之前,需要先了解其核心类层次结构。
Qt核心类层次
QObject是整个Qt对象系统的基类,位于Qt框架的核心位置。它提供了两个最重要的特性:信号与槽机制(用于对象间的通信)以及对象树管理(用于自动内存管理)。
QWidget继承自QObject,是所有用户界面组件的基类。常见的按钮、文本框、列表框等控件都是从QWidget派生而来的。
QMainWindow是QWidget的子类,专门用于创建应用程序的主窗口,提供了菜单栏、工具栏、状态栏等标准主窗口元素。
QDialog同样是QWidget的子类,主要用于创建模态或非模态的对话框窗口,如文件对话框、消息框等。
常用快捷键
- Alt + Enter:在头文件中声明的函数定义,自动在源文件中生成对应的实现框架
- Ctrl + 空格:触发代码自动补全功能
按钮控件基本操作
//创建一个按钮并设置父窗口
QPushButton* button = new QPushButton(this);
//设置按钮显示文本
button->setText("点击这里");
//创建另一个按钮,同时指定父窗口和文本
QPushButton* button2 = new QPushButton("确认", this);
//调整按钮位置
button2->move(150, 50);
//调整按钮尺寸
button2->resize(120, 40);
//设置窗口默认大小
resize(800, 600);
//锁定窗口大小,禁止用户调整
setFixedSize(800, 600);
//设置窗口标题栏文本
setWindowTitle("我的应用程序");
对象树机制
Qt的对象树机制是其内存管理的重要组成部分。当创建的对象指定了QObject或其派生类作为父对象时,Qt会自动将子对象添加到父对象的管理列表中。当父对象被销毁时,其所有子对象也会自动被销毁,从而简化了内存管理工作,避免了内存泄漏。
信号与槽机制
信号与槽是Qt的核心通信机制,用于对象之间的松耦合交互。
//基本语法:connect(信号发送者, 信号, 信号接收者, 槽函数)
//创建一个按钮,点击后关闭主窗口
QPushButton* closeBtn = new QPushButton("关闭", this);
connect(closeBtn, &QPushButton::clicked, this, &QWidget::close);
connect函数的完整参数说明:
- sender:信号发送者的指针
- signal:发送的信号(函数指针形式)
- receiver:信号接收者的指针
- method:接收者处理的槽函数(函数指针形式)
自定义信号与槽
下面演示如何在师生场景中使用自定义信号和槽:
教师类头文件:
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号,只需要声明,不需要实现
//可以带参数,支持重载
void hunger();
void hunger(QString foodName);
};
学生类头文件:
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
public slots:
//槽函数需要声明和实现
//可以带参数,支持重载
void treat();
void treat(QString foodName);
};
学生类实现:
void Student::treat(QString foodName)
{
//将QString转换为char*输出
QByteArray buffer = foodName.toUtf8();
qDebug() << "请老师吃饭,老师要吃:" << buffer.constData();
}
连接带参数的重载信号和槽:
//使用函数指针处理重载问题
void (Teacher::*teacherSignal)(QString) = &Teacher::hunger;
void (Student::*studentSlot)(QString) = &Student::treat;
connect(teacher, teacherSignal, student, studentSlot);
//触发信号
emit teacher->hunger("红烧肉");
信号连接信号
一个信号可以触发另一个信号,形成信号链:
//创建一个按钮,点击后触发教师信号的发送
QPushButton* classBtn = new QPushButton("下课", this);
resize(600, 400);
//将按钮的点击信号连接到教师的信号
void (Teacher::*ts2)(void) = &Teacher::hunger;
connect(classBtn, &QPushButton::clicked, teacher, ts2);
断开信号连接:
disconnect(classBtn, &QPushButton::clicked, teacher, ts2);
Lambda表达式
Qt5引入了对Lambda表达式的支持,使得信号槽的使用更加灵活便捷:
//使用Lambda表达式实现按钮点击事件
QPushButton* actionBtn = new QPushButton("触发", this);
actionBtn->move(100, 0);
connect(actionBtn, &QPushButton::clicked, this, [=](){
//在Lambda中访问外部变量
emit teacher->hunger("糖醋排骨");
this->close(); //关闭当前窗口
});
Lambda表达式的常用形式为[=](),其中=表示按值捕获所有外部变量,()表示参数列表为空。