Qt学习笔记2
信号和槽机制
使用预定义的信号和槽
信号和槽机制属于Qt的特色机制,他提供了不同控件之间通信功能,每个控件都包含了预定义的信号和槽,我们也可以自己为类定义信号和槽,当一个类被继承的时候他的信号和槽也同样会被继承,一个类如果支持信号和槽他必须继承自QObject
比如我们想实现button和mainwindow之间的通信,当按钮被点击时mainwindow会被关闭
分析上面的案例,当点击button的动作发生时button向mainwindow发送信号,mainwindow接受信号并执行关闭(槽)
常见的信号与槽的链接方式如下:
connect(Object1,SIGNAL(signal),Object2,SLOT(slot)) //信号发送者,发送的信号(函数地址),信号接受者,接受和处理信号
我们打开帮助文档去看QPushButton的预定义信号
它本身并没有什么信号其信号主要继承父类的,我们点开QAbstractButton
四个信号分别对应着点击,按压,释放,切换(与状态有关)
再看看mainwindow都有哪些槽
connect(button,&PushButton::clicked,mainwindow,&mainwindow::close);
要注意需要关联的信号和槽的签名必须是等同的,即信号的参数类型和参数个数与槽的参数类型和参数个数相同
但是特殊情况下信号的参数可以多于槽的参数,但必须是最后几个参数,注意虽然数量上可以少但是类型必须一致即签名相同
信号与槽具有松散耦合的特点,即槽不知道哪些信号关联了自己,他只需要再有信号接受的时候进行相应就可以了,这样当被关联的对象再运行的时候被删除时,应用程序也不会崩溃
不过明显通过信号来调用槽的方法要比直接调用的方法要损失很多性能,不过再大多数情况下这种性能损失是值得的
使用自定义的信号和槽
class myPushButton : public QPushButton { Q_OBJECT public: explicit myPushButton(QWidget *parent = nullptr); ~myPushButton(); signals: //自定义信号 //不能有返回值可以有参数,只需要声明不需要实现 //可以重载 public slots: //自定义槽,在高级版本中可以不必写在slot关键字下,可以写在public或者全局之下 //不能有返回值 //可以重载 };
上面是自定义信号和槽的方法 ,下面我们看一个具体的案例,类repository会向类productor发送信号isEmpty表示容量未满请求产生一个产品,
class repository : public QWidget
{
Q_OBJECT public: explicit repository(QWidget *parent = nullptr); ~repository();
signals:
isEmpty(); public slots:
};
class productor : public QWidget
{ Q_OBJECT public: explicit productor(QWidget *parent = nullptr); ~productor(); signals:
public slots: void product(){ qDebug()<<"生产一个产品"; } };
然后再主程序中添加如下代码
connect(rep1,&repository::isEmpty,pro1,&productor);//链接函数
emit rep1->isEmpy();//触发信号
信号和槽的重载
当信号发生重载的时候,要指明具体是哪一个比如重载isEmpty()方法,使其指明需要哪种货物,并重载product()方法使其生产固定的产品
void isEmpty(QString name); void product(QString name){ qDebug()<<"生产一个"+name; }
同时在链接的时候每一个都要指明是哪一个信号,因为信号和对应槽的签名必须相同
void(repository::*repositorySignal)(QString)=&repository::isEmpty(); //声明函数指针 void(productor::*productSignal)(QString)=&productor::product(); //声明函数指针,注意由于product是成员函数所以必须带域名
connect(rep1,repositorySignal,pro1,productSignal);
//进行链接
对于Qt4及以前的版本可以使用
connnect(Object1,SIGNAL(signal),Object2,SLOT(slot)));
的写法但是不推荐,因为并不会检测参数
信号和槽的触发方式
1.信号可以触发其他信号
connect(Object1,SIGNAL(signal1),Object2,SIGNAL(signal1));
2.同一个信号可以与多个槽相连
connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot2));
connect(Object1,SIGNAL(signal2),Object3,SIGNAL(slot1));
3.同一个槽可以相应同一个信号
connect(Object1,SIGNAL(signal2),Object2,SIGNAL(slot2));
connect(Object3,SIGNAL(signal2),Object2,SIGNAL(slot2));
有的时候系统预定义的槽可能含有参数这是可以用lambda表达式的方法对槽进行一定的封装
断开信号
disconnnect(Object1,SIGNAL(signal),Object2,SLOT(slot)));
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)