一、简介

由于博主本人是初学者对QT的机制不了解,所以遇到了一个比较大的坑,特此记录一下。我遇到的问题是无法在静态函数中向另外一个类发送信号。解决办法:先将信号发送给同类中的普通函数,然后在从普通函数中发送信号给外部类。

二、C与C++中static的用法

这里不是介绍QT静态函数信号的发送吗,和static的用法有什么联系,因为在编写代码中会出现静态成员无法访问普通成员的错误,这里我复制了菜鸟教程的图片。



接下来先了解一下static的用法。

  1. C语言中static的作用

    主要有三个作用:隐藏性、持久性、默认值为0
  • 隐藏性:当我们同时编译多个文件时,所有未加 static 前缀的全局变量和函数都具有全局可见性。
  • 持久性:在函数内部使用static修饰变量时,不仅可以是变量具有隐藏性,还能增加变量生命。
  • 默认初始化为 0:在静态数据区,内存中所有的字节默认值都是 0x00,其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。

    想了解具体的用法可以去菜鸟教程学习《C 语言中 static 的作用》。
  1. 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之静态函数发送信号的更多相关文章

  1. Qt 使用 lambda 表达式做为槽函数时为什么使用 QObject::sender() 获取到的发送信号对象指针为空?

    /*! Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; ...

  2. QT槽函数获取信号发送对象

    Qt 在槽函数中获取信号发送对象 Qt中提供了一个函数 qobject_cast(QObject *object),可以通过这个函数判断信号发出对象 Qt 帮助文档的解释: Returns the g ...

  3. 第七章 探秘Qt的核心机制-信号与槽

    第七章 探秘Qt的核心机制-信号与槽 注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用 ...

  4. 在Qt中将函数发送到主线程执行

    考虑这样一种需求,使用Qt的线程类QThread在后台执行操作(比如说拷贝文件)的时候发生了错误,产生了一个错误信息需要提醒给用户,在后台输出很显然是不够的,因为用户可能根据就没有任何控制台可供程序输 ...

  5. QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)

    QThread 继承 QObject..它可以发送started和finished信号,也提供了一些slot函数. QObject.可以用于多线程,可以发送信号调用存在于其他线程的slot函数,也可以 ...

  6. 2.QT-窗口组件(QWidget),QT坐标系统,初探消息处理(信号与槽)

    本章主要内容如下: 1) 窗口组件(QWidget) 2) QT坐标系统 3) 消息处理(信号与槽) 窗口组件(QWidget) 介绍 Qt以组件对象的方式构建图形用户界面 Qt中没有父组件的顶级组件 ...

  7. Qt对象模型之一:信号和槽

    一.信号和槽机制概述 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal).这种发出是没有目 ...

  8. Linux 发送信号

    使用kill命令 --在命令行执行kill命令.向指定进程发送信号. 使用kill函数 int kill(pid_t pid,int sig); --参数pid指定一个要杀死的进程,而sig是要发送的 ...

  9. Linux 命令 - kill: 向进程发送信号

    kill 命令通常用来 “杀死”(终止)进程,它可以用来终止运行不正常的程序或者反过来拒绝终止的程序.kill 命令准确地说并不是 “杀死” 进程,而是给进程发送信号(signal). 和文件一样,进 ...

随机推荐

  1. CentOS 永久修改系统时间

    1.查看当前系统时间 date       2.修改当前系统时间 date -s "2018-2-22 19:10:30       3.查看硬件时间 hwclock --show      ...

  2. MeteoInfo-Java解析与绘图教程(一)

    MeteoInfo-Java解析与绘图教程(一) 已经进入开发行业很多年了,这两年一直从事气象开发行业,为此对气象绘图有了新的见解 像色斑图与卫星图一直都有python去绘制,在偶然的情况下,我接触到 ...

  3. .NET Core/.NET5/.NET6 开源项目汇总13:模板引擎

    系列目录     [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...

  4. 物理机安装ESXi并优化部署虚拟机

    物理机配置 CPU,BIOS中启用虚拟化(VT-X) 内存和硬盘,内存尽量大.硬盘最好SSD,内存的大小和硬盘的速度直接决定了虚拟机运行的快慢 网络,至少一块千兆网卡(vSphere7.0版本以后支持 ...

  5. Salesforce Integration 概览(七) Data Virtualization数据可视化

    本篇参考:https://resources.docs.salesforce.com/sfdc/pdf/integration_patterns_and_practices.pdf Salesforc ...

  6. 编程熊讲解LeetCode算法《二叉树》

    大家好,我是编程熊. 往期我们一起学习了<线性表>相关知识. 本期我们一起学习二叉树,二叉树的问题,大多以递归为基础,根据题目的要求,在递归过程中记录关键信息,进而解决问题. 如果还未学习 ...

  7. 简单的整合 shiro + SpringMVC 例子

    简单的整合shiro和springmvc的例子 想要整合Shiro和springmvc,在网上找了很多例子,感觉都有一点复杂.所以就自己写了一个最简单整合项目,记录在这里以备后面查看. 这个例子包含如 ...

  8. 将vim打造成Java IDE

    需要的插件列表: Taglist Conque Shell FuzzyFinder NERDTree javaComplete 其他选项: JavaKit exVim winmanager (Depr ...

  9. kali虚拟机安装VMTools、更新源、安装docker、配置sqli-labs

    一.安装VMTools: 传送门:关于安装VMTools 跟其他版本的虚拟机安装VMTools没什么区别,也得连网(我是kali用dhcp开nat模式) 之后按照上面的链接根据博主的步骤一步一步来即可 ...

  10. 附件携马之CS免杀shellcode过国内主流杀软

    0x01 写在前面 其实去年已经写过类似的文章,但是久没用了,难免有些生疏.所谓温故而知新,因此再详细的记录一下,一方面可以给各位看官做个分享,另一方面等到用时也不至于出现临阵磨枪的尴尬场面. 0x0 ...