QT之静态函数发送信号
一、简介
由于博主本人是初学者对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之静态函数发送信号的更多相关文章
- Qt 使用 lambda 表达式做为槽函数时为什么使用 QObject::sender() 获取到的发送信号对象指针为空?
/*! Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; ...
- QT槽函数获取信号发送对象
Qt 在槽函数中获取信号发送对象 Qt中提供了一个函数 qobject_cast(QObject *object),可以通过这个函数判断信号发出对象 Qt 帮助文档的解释: Returns the g ...
- 第七章 探秘Qt的核心机制-信号与槽
第七章 探秘Qt的核心机制-信号与槽 注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用 ...
- 在Qt中将函数发送到主线程执行
考虑这样一种需求,使用Qt的线程类QThread在后台执行操作(比如说拷贝文件)的时候发生了错误,产生了一个错误信息需要提醒给用户,在后台输出很显然是不够的,因为用户可能根据就没有任何控制台可供程序输 ...
- QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)
QThread 继承 QObject..它可以发送started和finished信号,也提供了一些slot函数. QObject.可以用于多线程,可以发送信号调用存在于其他线程的slot函数,也可以 ...
- 2.QT-窗口组件(QWidget),QT坐标系统,初探消息处理(信号与槽)
本章主要内容如下: 1) 窗口组件(QWidget) 2) QT坐标系统 3) 消息处理(信号与槽) 窗口组件(QWidget) 介绍 Qt以组件对象的方式构建图形用户界面 Qt中没有父组件的顶级组件 ...
- Qt对象模型之一:信号和槽
一.信号和槽机制概述 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal).这种发出是没有目 ...
- Linux 发送信号
使用kill命令 --在命令行执行kill命令.向指定进程发送信号. 使用kill函数 int kill(pid_t pid,int sig); --参数pid指定一个要杀死的进程,而sig是要发送的 ...
- Linux 命令 - kill: 向进程发送信号
kill 命令通常用来 “杀死”(终止)进程,它可以用来终止运行不正常的程序或者反过来拒绝终止的程序.kill 命令准确地说并不是 “杀死” 进程,而是给进程发送信号(signal). 和文件一样,进 ...
随机推荐
- MySQL执行计划【explain】详解
本文已经收录到github仓库,仓库用于分享Java相关知识总结,包括Java基础.MySQL.Springboot.mybatis.Redis.rabbitMQ等等,欢迎大家提pr和star! gi ...
- [数据结构-平衡树]普通 FHQ_Treap从入门到精通(注释比代码多系列)
普通 FHQ_Treap从入门到精通(注释比代码多系列) 前提说明,作者写注释太累了,文章里的部分讲解来源于Oi-wiki,并根据代码,有部分增改.本文仅仅发布于博客园,其他地方出现本文,均是未经许可 ...
- SpringBoot-静态资源加载-源码
目录 静态资源映射规则 什么是webjars 呢? 第二种静态资源映射规则 参考链接 静态资源映射规则 SpringBoot中,SpringMVC的web配置都在 WebMvcAutoConfigur ...
- SpringCloud升级之路2020.0.x版-14.UnderTow AccessLog 配置介绍
本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford server: u ...
- Golang语言系列-11-goroutine并发
goroutine 并发 概念 package main import ( "fmt" "time" ) /* [Go语言中的并发编程 goroutine] [ ...
- Golang语言系列-04-运算符
运算符 Go语言内置的运算符有 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 算术运算符 package main import "fmt" func main() { ...
- DHCP服务-自动管理IP地址和分配固定IP
dhcp服务 端口:67 配置文件:/etc/dhcp/dhcpd.conf 自动分配IP: 一. 安装服务:yum install dhcp 安装过程省略 二.首先,看到配置文件中啥也没有,他的配置 ...
- Proteus仿真—51单片机实现AC信号测频、显示、双机通信
文章目录 一.原理图部分 二.源码部分 单片机1 单片机2 在Proteus仿真软件里面使用STC89C52实现指定频率的AC信号的测频.显示.双机通信. 一.原理图部分 整体的电路图如示: DC-A ...
- MATLAB—M函数文件
文章目录 一.M文件 1.脚本文件和函数文件的区别 二.M函数文件 1.创建方法 2.文件形式 2.函数形参及注释 3.函数的调用 4.函数变量 5.主函数.子函数 三.函数句柄 一.M文件 首先,要 ...
- SQL 练习23
查询男生.女生人数 SELECT Ssex,COUNT(Ssex) 人数 from Student GROUP BY Ssex