元对象和动态属性
动态属性
obj->setProperty("isGirl", true) // 动态添加属性,为obj增添一个属性,并赋值true
qDebug() << obj->property("isGirl").toBool(); // 获取动态属性 obj->setProperty("isGirl", true) // 动态添加属性,为obj增添一个属性,并赋值true
qDebug() << obj->property("isGirl").toBool(); // 获取动态属性 通过勾选框QCheckBox来设置字体
Dialog::click(bool checked){ // 勾选框的选中状态是checked
QFont font = ui->text->font(); // 获取text的字体
font.setUnderline(true); // 设置下划线
ui->text->setFont(font);
}QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot())); // SIGNAL和SLOT是宏,用于将参数转化为相应的字符串,继承QObject的子类可以省略命名空间QObject::一个信号可以连接多个槽函数
多个信号可以连接同一个槽函数
一个信号可以连接另一个信号
QMetaObject::Connection QObject::connect(sender, &signal, receiver, &method, Qt::connectionType = Qt::AutoConnection)); sender和receiver都是对象指针
signal是信号函数,只有声明不需要定义实现,在sender对应的类的signals:中定义。
method是槽函数,需要在receiver的.h文件中声明public slots:或private slots:并且在cpp中定义实现。
Qt::connectionType可选参数,表示信号与槽之间的关联方式:
Qt::AutoConnection默认值,自动确定关联方式
Qt::DirectConnection信号发射时,槽立即执行,槽函数与信号在同一线程
Qt::QueuedConnection事件循环回到接收者线程后执行槽,槽与信号不在同一线程
Qt::BlockingQueueConnection与Qt::QueuedConnection相似,信号线程阻塞直到槽执行完毕。信号与槽不能在同一线程,否则会死锁
信号和槽函数带参:
signals:
connect(ui->sender, &QCheckBox::clicked, this, qOverload<bool>(&Widget::method)); // qOverload<参数>
private slots:
void QCheckBox::clicked(bool checked = false); // QCheckBox有选中和未选中两种状态,分别对应checked的true和false待补充
解除一个sender的所有signal连接
disconnect(myObject, nullptr, nullptr, nullptr); // 静态函数
myObject->disconnect(); // 成员函数解除一个sender的特定signal的所有连接
disconnect(myObject, SIGNAL(mySignal()), nullptr, nullptr); // 静态函数
myObject->disconnect(SIGNAL(mySignal())); // 成员函数解除与一个receiver的所有连接
disconnect(myObject, nullptr, myReceiver, nullptr); // 静态函数
myObject->disconnect(myReceiver); // 成员函数解除一堆特定的信号和槽的连接
disconnect(ui->sender, &QCheckBox::clicked, this, &Widget::method);槽函数里使用QObject::sender()获取信号发送者的指针
QCheckBox * b = qobject_cast<QCheckBox *>(sender()); // qobject_cast强制类型转换,将sender()的返回转换为QCheckBox *类型QString name = "zhang";
int age = 999;
emit func(name, age);信号函数不能有返回值,可以带参
// widget.h
#pragram once // 该头文件只能出现一次
#include <QWidget>
namespcace Ui { // 命名空间
class Widget; // ui_widget.h文件里定义的类,外部声明
}
class Widget: public QWidget {
Q_OBJECT // 宏,使用信号与槽等META层机制时必须添加,一般继承于QObject的子类都要添加这个宏
public:
explict Widget(QWidget * parent = nullptr); // 若传入parent则图形化对象之间有了父子容器的关系
~Widget(); // 析构函数
private:
Ui::Widget * ui; // Ui::Widget搭配上面声明的命名空间,指向可视化界面,也就是.ui设计好的窗口界面
};// widget.cpp
#include "widget.h" // 包含自己的目录用引号。
#include "ui_widget.h" // 每次编译,编译器都会自动生成该头文件的代码
Widget::widget(QWidget * parent): QWidget(parent), ui(new Ui::Widget) { // 类成员冒号初始化,先调用父类的构造函数QWidget(parent),再ui = new Ui::Widget。使用ui指针可以对控件进行操作,例如ui->helloLabel->setText("hello");
ui->setupUi(this); // 实现了组件的各种设置、信号与槽的关联
}
Widget::~widget() {
delete ui; // 对象树机制,删除了ui,相当于将整个窗口包含其中所有的控件都删了
}