QT之静态函数发送信号
2021-09-13 16:06
881 查看
一、简介
由于博主本人是初学者对QT的机制不了解,所以遇到了一个比较大的坑,特此记录一下。我遇到的问题是无法在静态函数中向另外一个类发送信号。解决办法:先将信号发送给同类中的普通函数,然后在从普通函数中发送信号给外部类。
二、C与C++中static的用法
这里不是介绍QT静态函数信号的发送吗,和static的用法有什么联系,因为在编写代码中会出现静态成员无法访问普通成员的错误,这里我复制了菜鸟教程的图片。 接下来先了解一下static的用法。
- C语言中static的作用 主要有三个作用:隐藏性、持久性、默认值为0
- 隐藏性:当我们同时编译多个文件时,所有未加 static 前缀的全局变量和函数都具有全局可见性。
- 持久性:在函数内部使用static修饰变量时,不仅可以是变量具有隐藏性,还能增加变量生命。
- 默认初始化为 0:在静态数据区,内存中所有的字节默认值都是 0x00,其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。 想了解具体的用法可以去菜鸟教程学习《C 语言中 static 的作用》。
- C++ 中static的作用 C++中使用static需要主要的地方
- 静态成员函数中不能调用非静态成员。
- 非静态成员函数中可以调用静态成员。因为静态成员属于类本身,在类的对象产生之前就已经存在了,所以在非静态成员函数中是可以调用静态成员的。
- 静态成员变量使用前必须先初始化(如 int MyClass::m_nNumber = 0;),否则会在 linker 时出错。
修饰成员变量
- 静态数据成员可以实现多个对象之间的数据共享,它是类的所有对象的共享成员,它在内存中只占一份空间,如果改变它的值,则各对象中这个数据成员的值都被改变。
- 静态数据成员是在程序开始运行时被分配空间,到程序结束之后才释放,只要类中指定了静态数据成员,即使不定义对象,也会为静态数据成员分配空间。
- 静态数据成员可以被初始化,但是只能在类体外进行初始化,若未对静态数据成员赋初值,则编译器会自动为其初始化为 0。
- 静态数据成员既可以通过对象名引用,也可以通过类名引用。
修饰成员函数
- 静态成员函数和静态数据成员一样,他们都属于类的静态成员,而不是对象成员。
- 非静态成员函数有 this 指针,而静态成员函数没有 this 指针。
- 静态成员函数主要用来方位静态数据成员而不能访问非静态成员。 想了解具体的用法可以去菜鸟教程学习《C/C++ 中 static 的用法全局变量与局部变量》。
三、程序源码
ClassA.h 文件
#ifndef CLASSA_H #define CLASSA_H #include <QObject> #include <iostream> class ClassA : public QObject { Q_OBJECT public: ClassA(); ~ClassA(); static void SignalGeneration(); //静态函数,信号将从此函数发生 private: static ClassA *myClassA; //它在内存中只占一份空间 signals: void SigExternal(QString str); //向外部的类发送信号 void SigInsideDelier(char *str); //发送信号到此类的信号槽 private slots: void SlotInsideDelier(char *str); //内部槽 用于响应内部信号 }; #endif // CLASSA_H
ClassA.cpp文件
#include "ClassA.h" ClassA *ClassA::myClassA = NULL; // 静态成员变量使用前必须先初始化,否则使用是会提示变量未定义 ClassA::ClassA() { myClassA = this; connect(this, &ClassA::SigInsideDelier, [this](char *str) { emit SlotInsideDelier(str); }); } void ClassA::SignalGeneration() { const char *str = "信号生产成功"; emit myClassA->SigInsideDelier((char *)str); } void ClassA::SlotInsideDelier(char *str) { emit SigExternal(QString(str)); } ClassA::~ClassA() { }
widget.h文件
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include "ClassA.h" QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_pushButton_clicked(); void classA_msg(QString str); private: Ui::Widget *ui; }; #endif // WIDGET_H
widget.cpp文件
#include "widget.h" #include "ui_widget.h" #include <iostream> #include "ClassA.h" using namespace std; ClassA *classA; Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { classA = new ClassA(); connect(classA, SIGNAL(SigExternal(QString)), this, SLOT(classA_msg(QString))); //注意这里传递信号必须使用QString不能使用char *,否则接收数据会异常,具体原因未知 ui->setupUi(this); } Widget::~Widget() { delete classA; delete ui; } void Widget::on_pushButton_clicked() { ClassA::SignalGeneration(); } void Widget::classA_msg(QString str) { ui->plainTextEdit->appendPlainText(str); }
程序界面
四、运行测试
参考文献
C 语言中 static 的作用:https://www.runoob.com/w3cnote/c-static-effect.html C/C++ 中 static 的用法全局变量与局部变量:https://www.runoob.com/w3cnote/cpp-static-usage.html Qt知识点梳理 —— 静态函数发送信号:https://blog.csdn.net/tingzhiyi/article/details/112631489
相关文章推荐
- Qt 静态函数中如何发送信号
- QT4 键盘按键发送自定义信号
- Qt: for循环产生多线程,主线程向子线程发送信号
- Qt跨线程发送信号与元数据
- QT 跨线程发送信号非元数据信号解决
- Qt跨线程发送信号与元数据
- qt 获取发送信号的对象
- qt下信号发送机制
- Qt在信号中如何发送自定义结构体,或者发送多个自定义参数
- [QtSignal]窗口间自定义信号的发送与接受
- QT c++ 发送信号到 QML 槽函数 踩过的坑
- 【Qt】针对信号发送间隔短而槽耗时大的两种解决方案
- ClockThread自定义信号的发送和接收(QtSDK thread/ClockThread)
- qt 槽函数识别发送的信号
- Qt基础 06_信号和槽(二)自定义信号和槽的实例
- Linux Signal (6): 发送信号的kill和raise 函数
- QT信号槽机制
- 解决Qt中某类的槽无法连接另一类的信号的问题
- PyQt5系列教程(十一)发送信号时传参
- Qt实现图片移动(2)定时器和信号槽