一、简介

由于博主本人是初学者对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. 「必知必会」最细致的 ArrayList 原理分析

      从今天开始也正式开 JDK 原理分析的坑了,其实写源码分析的目的不再是像以前一样搞懂原理,更重要的是看看他们编码风格更进一步体会到他们的设计思想.看源码前先自己实现一个再比对也许会有不一样的收获! ...

  2. kivy里rgb,rgba颜色相关知识,以及支持十六进制颜色值方法

    rgb,rgba在kivy里的格式为如下: rgb:1,1,1---->每个参数为0-1的数值(如0.1),也就是说第一位如果是0.1意思是10%的红色,由r代表,g代表绿色,b代表蓝色 rgb ...

  3. Java异常02——自定义异常

    Error与Exception与自定义异常 Error与Exception Error Exception 自定义异常 快捷键: ctrl + alt + t  package exception.d ...

  4. XCTF-simple unpack

    题目提示这是一个加壳的二进制文件,拖到exeinfope,是UPX壳. 这里我们用linux命令upx -d脱壳. 脱完壳之后拉入ida64中分析.找到main函数,可以看到这一句可以是输出flag的 ...

  5. HCIA-网络层包结构

    网络层 关心-->转发 IPV4协议 IPV6协议 寻址 转发 标识位置 IPV6: 86DD MAC定位局部 网络定位全局 对于上层数据如果过大,网络层可以分组,实现分组转发 环路:发送了一个 ...

  6. 【Lua篇】静态代码扫描分析(三)语法分析

    一.语法分析 通过将词法分析获取的Token流按照目标语言的语法进行解析的过程,例如解析函数声明.函数调用.变量声明.各种语句等. 二.Lua语法分析 在写语法分析程序前,先需要了解Lua的语句和语法 ...

  7. Windows上的暗色调Puppet书籍翻译写作环境

    翻译环境包括两个部分,写作部分和电子书,Windows上,前者用gVim,后者用SumatraPDF,二者都是绿色软件,都可以定义成暗色系风格. gVim 全屏需要使用一个叫做gvimfullscre ...

  8. SpringBoot开发一

    项目介绍 牛客高级项目课,主要是完成牛客网的讨论社区的搭建.项目在github上. 涉及到的技术架构: Spring,SpringBoot,SpringMVC,MyBatis,Redis,Kafka( ...

  9. Redis 实战篇:巧用Bitmap 实现亿级海量数据统计

    在移动应用的业务场景中,我们需要保存这样的信息:一个 key 关联了一个数据集合. 常见的场景如下: 给一个 userId ,判断用户登陆状态: 显示用户某个月的签到次数和首次签到时间: 两亿用户最近 ...

  10. GitHub自动化部署(CD) asp.net core 5.0 项目(免费空间)

    这里我简单介绍一下使用Github自动化部署自己项目到Heroku云服务器上,Heroku竟然是一个很非常老牌的云平台服务商,竟然还没听说过,网上一查2010被Salesforce收购,网上有很多关于 ...