信号和槽机制
信号(Signal)和槽机(Slot)制 是Qt 特有的,独创的一种对象间通信的机制。
信号 是指发送对象给出的函数和参数的一种通知机制。
槽是指接受者和接收对象执行的函数。
QAbstractButton 的信号
void clicked(bool checked = false) // 点击信号(给出按钮的值)
void pressed() // 按钮按下
void released() // 释放按钮
void toggled(bool checked) // 按钮状态变化。
槽是对象自定义的函数,他可以象普通成员函数一样调用。还可以连接某个对象的信号。
槽函数的定义方法
class MyWidget: public QObject类或他的子类 {
Q_OBJECT // 必须添加此宏
public slots:
返回类型 槽函数名1(参数列表) {函数体}
返回类型 槽函数名2(参数列表) {函数体}
};
信号和槽的连接方式
使用QObject::connect() 函数进行连接
// 方法1(QT4及之前必须使用此种方法)
//connect(发送信号的对象, SIGNAL(发送对象的信号函数),
// 接收对象, SLOT(接收对象的成员函数));
QObject::connect(btn, SIGNAL(clicked(int)),
obj, SLOT(onBtnPressed()));
// 方法2(QT5之后可用的方法)
//connect(发送信号的对象, 发送对象的信号成员函数地址),
// 接收对象, 接收对象的成员函数地址);
QObject::connect(btn, &PushButton::clicked(int)),
obj, &MyWidget::onBtnPressed);
// 方法3(QT5之后可用的方法)
//connect(发送信号的对象, 发送对象的信号成员函数地址), 全局函数或lambda表达式);
QObject::connect(btn, &PushButton::clicked(int)),
lambda表达式);
信号的定义和触发
定义信号时在类声明中使用 singals 关键字,声明槽函数(仅声明,不用实现)。
语法格式
class MyWidget: public QObject类或他的子类 {
Q_OBJECT // 必须添加此宏
signals:
返回类型 信号函数名1(参数列表);
返回类型 信号函数名1(参数列表);
};
触发信号
触发信号也叫提交信号,在Qt的QObject类的成员函数内使用 emit 关键字来触发信号。
触发信号会调用所有已经连接此信号的函数。
语法如下
emit 信号函数名(调用实参);
示例:登录对话框
loginwidget.h
#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H
#include <QLineEdit>
#include <QCheckBox>
#include <QLabel>
#include <QWidget>
class LoginWidget : public QWidget
{
Q_OBJECT
public:
explicit LoginWidget(QWidget *parent = nullptr);
public slots:
void onBtnLogin(void); // 点击登陆的槽函数
signals:
private:
QLineEdit * username;
QLineEdit * password;
QCheckBox * autoSavePasswd;
QLabel * errorHint; // 用于显示错误提示
};
#endif // LOGINWIDGET_H
loginwidget.cpp
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QCheckBox>
#include <QDebug>
#include "loginwidget.h"
LoginWidget::LoginWidget(QWidget *parent) : QWidget(parent)
{
QVBoxLayout *vlayout1 = new QVBoxLayout(this);
// 用水平布局将QLabel 和 QLineEdit放在一起。
QHBoxLayout *hlayout1 = new QHBoxLayout;
vlayout1->addLayout(hlayout1); // 加入垂直布局
QLabel * label = new QLabel("用户名:");
label->setMinimumWidth(60);
label->setAlignment(Qt::AlignRight);
// 用户名的编辑框
username = new QLineEdit();
hlayout1->addWidget(label);
hlayout1->addWidget(username);
// 用水平布局将QLabel 和 QLineEdit放在一起。
QHBoxLayout *hlayout2 = new QHBoxLayout;
vlayout1->addLayout(hlayout2); // 加入垂直布局
QLabel * label2 = new QLabel("密码:");
label2->setAlignment(Qt::AlignRight);
label2->setMinimumWidth(60);
// 密码的编辑框
password = new QLineEdit();
hlayout2->addWidget(label2);
hlayout2->addWidget(password);
autoSavePasswd = new QCheckBox("记住密码");
vlayout1->addWidget(autoSavePasswd);
// 登陆失败提示:
errorHint = new QLabel("用户名或密码错误!");
errorHint->hide(); // 默认隐藏。
vlayout1->addWidget(errorHint);
// 注册登陆按钮
QHBoxLayout *hlayout3 = new QHBoxLayout;
vlayout1->addLayout(hlayout3);
hlayout3->addWidget(new QPushButton("注册"));
QPushButton * loginBtn = new QPushButton("登陆");
hlayout3->addWidget(loginBtn);
// 设置登陆和注册的间距
hlayout3->setSpacing(30);
// 设置 垂直方向的间距。
vlayout1->setSpacing(15);
// 设置外边距。
vlayout1->setContentsMargins(50, 50, 50, 50);
// 按钮的Pressed 信号 当前对象的 onBtnLogin 连接
// 方法1
// connect(loginBtn, SIGNAL(pressed()),
// this, SLOT(onBtnLogin()));
// 方法2
connect(loginBtn, &QPushButton::pressed,
this, &LoginWidget::onBtnLogin);
// 方法3
// connect(loginBtn, &QPushButton::pressed,
// [=](){
// qDebug() << "登陆按钮被点击";
// errorHint->show();
// });
}
void LoginWidget::onBtnLogin(void)
{
QString name = username->text();
QString pass = password->text();
qDebug() << "用户名:" << username->text();
qDebug() << "密码:" << password->text();
qDebug() << "记住密码:" << autoSavePasswd->isChecked();
//以下做登陆的操作。
if (name=="root" && pass == "123456") {
// 新建另外一个对话框并打开
QWidget *chatWidget = new QWidget;
chatWidget->setWindowTitle(QString("用户:") +name);
chatWidget->show();
this->close();
} else {
errorHint->show();
}
}
键盘事件
基于QWidget 的对象在有键盘按下时会收到 KeyPressEvent 事件,按键抬起时会收到 KeyReleaseEvent事件。用户可以通过重写此函数来接收来自键盘的事件。
键盘事件的处理函数:
void QWidget::keyPressEvent(QKeyEvent *event);
void QWidget::keyReleaseEvent(QKeyEvent *event)
event是指向按键信息的对象。
QKeyEvent对象的常用成员函数如下:
int key() const
bool isAutoRepeat() const
鼠标事件
时间处理函数
void QWidget::mousePressEvent(QMouseEvent *event);
void QWidget::mouseReleaseEvent(QMouseEvent *event);
void QWidget::mouseDoubleClickEvent(QMouseEvent *event);
void QWidget::mouseMoveEvent(QMouseEvent *event);
event 对象是QMouseEvent 对象,内部有鼠标按键的信息