赞
踩
写Qt文章貌似没有信号槽内容就是没有灵魂。(●’◡’●)
Qt的信号和槽机制是一种用于对象间通信的强大且灵活的方法,它允许组件间的解耦以及响应式的编程风格。在Qt中,当一个事件发生时(例如,用户点击了一个按钮),相应组件会发射一个信号;而其他组件可以通过槽函数来接收和处理这些信号。
信号是Qt对象中定义的特殊成员函数,它们不具有返回值,也不需要显式调用。信号通常用来表示一个事件的发生,例如按钮点击 (clicked())、状态改变 (textChanged()) 等。信号的声明是在类定义中,且该类必须包含Q_OBJECT宏。
槽是可被信号触发的成员函数。槽可以是任意形式的可调用实体,包括普通的成员函数、Lambda表达式或者全局函数。槽函数可以处理信号带来的数据,执行相应的操作。
QObject::connect()函数是用来建立信号和槽之间的联系。当信号被发射时,与其连接的所有槽将会按照连接顺序被自动调用。
// 首先,定义一个包含信号和槽的类
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = nullptr);
signals:
void buttonClicked(); // 定义一个信号
public slots:
void onButtonClicked(); // 定义一个槽函数
private:
QPushButton m_button;
};
// 实现类
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
m_button.setText("Click me!");
connect(&m_button, &QPushButton::clicked, this, &MyWidget::onButtonClicked); // 连接信号和槽
}
// 槽函数实现
void MyWidget::onButtonClicked()
{
qDebug() << "Button was clicked!";
}
// 主函数中创建并显示窗口
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
示例代码过于简单,不进行讲解了。
bool QObject::connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *slot,
Qt::ConnectionType type = Qt::AutoConnection);
sender: 发送信号的对象的指针,这里通常是发射信号的那个QObject子类对象。
signal: 字符串形式的信号名称。在Qt 5及以后版本中,更推荐使用指针到成员函数的形式指定信号,如 &QPushButton::clicked。
receiver: 接收信号并调用槽的对象指针。
slot: 字符串形式的槽函数名称,同样在Qt 5后推荐使用指向成员函数的指针,如 &MyWidget::onButtonClicked。
type: 连接类型,决定信号与槽的调用时机和线程关系,常见的有:
信号和槽之间还可以传递参数,信号的参数类型和数量必须与槽的匹配。例如,若信号是void signal(QString text),则槽可以是void slot(QString text)。
在Qt 5中,为了支持类型安全和更好的编译时检查,推荐使用新式的连接方式,避免使用字符串形式的信号和槽名称。同时,对于带有参数的信号和槽,无需再使用SIGNAL()和SLOT()宏。例如:
connect(senderObject, &SenderClass::valueChanged, receiverObject, &ReceiverClass::processValue);
以上代码连接了SenderClass的valueChanged()信号和ReceiverClass的processValue()槽,两个函数应当具有匹配的参数列表。
Qt中信号槽关联有多种不同的写法,以下是几种常见的关联方式:
QObject::connect()
函数手动关联connect(sender, SIGNAL(signalSignature), receiver, SLOT(slotFunction()));
例如:
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked()));
connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
例如:
connect(ui->pushButton, &QPushButton::clicked, this, &MyClass::onPushButtonClicked);
如果你遵循Qt Creator的信号槽命名规范,可以在.cpp
文件中利用Ui类的自动连接功能:
void MyClass::setupUi(QMainWindow *parent)
{
...
setupUi(parent);
...
}
void MyClass::on_pushButton_clicked() // 自动关联到pushButton的clicked信号
{
// 处理点击事件的代码
}
connect(sender, &SenderClass::signalName, this, [this](){
// Lambda函数体,处理信号的动作
});
Qt5中支持Qt4的connect的写法。
每种连接方式都需要考虑线程环境,可以选择合适的Qt::ConnectionType
作为connect()
函数的最后一个参数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。