当前位置: 首页 > news >正文

Qt不同窗口类的控件信号和槽绑定

做项目的时候我使用了Qt,不同的界面使用了不同的ui的类进行解耦,但是信号和槽绑定的时候可能是不同界面的控件互相进行通讯连接,然而ui指针对于各个界面类是私有成员,无法直接跳过访问,在网上看了一些参考资料,感觉都不太好,以下是几种可行的方案:

  1. 把ui成员变成一个public成员,但这样不仅破坏了封装性,而且把所有的ui成员全部暴露出去了。
  2. 使用一个static指针来将当前的界面指针传到外面,但是如果多个界面都要这样设计指针满天飞感觉非常的凌乱。
  3. 使用类似职责链模式将信号和槽进行一层层传递,但是要写很多层,太麻烦了。

思来想去,我想了一个解决办法,我们需要的是控件的指针,那么不妨直接用一个类管理这些指针,就可以最小化暴露指针成员。具体的思路是这样的:使用一个哈希表,键自己定,值是一个控件的指针,为了所有的控件都可以放入哈希表,哈希表的值设置为void*,取出来的时候用户再自己进行强转。

  • SignalSlotObjectMap.h
#ifndef SIGNAL_SLOT_OBJECT_MAP_H
#define SIGNAL_SLOT_OBJECT_MAP_H
#include <QString>
#include <QMap>
class SignalSlotObjectMap
{
public:
    static void InsertSignalObjectMap(const QString &key, void *value);
    static void InsertSlotObjectMap(const QString &key, void *value);
    static void *FindSignalObjectMap(const QString &key);
    static void *FindSlotObjectMap(const QString &key);
    static void DebugPrintMap(void);

private:
    static QMap<QString, void *> s_signalObjectMap;
    static QMap<QString, void *> s_slotObjectMap;
};

#endif // SIGNAL_SLOT_OBJECT_MAP_H
  • SignalSlotObjectMap.cpp
#include "SignalSlotObjectMap.h"
#include <QDebug>
// 初始化静态成员变量
QMap<QString, void *> SignalSlotObjectMap::s_signalObjectMap = {};
QMap<QString, void *> SignalSlotObjectMap::s_slotObjectMap = {};

void SignalSlotObjectMap::InsertSignalObjectMap(const QString &key, void *value)
{
    auto it = s_signalObjectMap.find(key);
    if (it != s_signalObjectMap.end())
        return;
    s_signalObjectMap.insert(key, value);
}

void SignalSlotObjectMap::InsertSlotObjectMap(const QString &key, void *value)
{
    auto it = s_slotObjectMap.find(key);
    if (it != s_slotObjectMap.end())
        return;
    s_slotObjectMap.insert(key, value);
}

void *SignalSlotObjectMap::FindSignalObjectMap(const QString &key)
{
    auto it = s_signalObjectMap.find(key);
    if (it != s_signalObjectMap.end())
        return it.value();
    return nullptr;
}

void *SignalSlotObjectMap::FindSlotObjectMap(const QString &key)
{
    auto it = s_slotObjectMap.find(key);
    if (it != s_slotObjectMap.end())
        return it.value();
    return nullptr;
}

void SignalSlotObjectMap::DebugPrintMap(void)
{
    qDebug() << "s_signalObjectMap:";
    for (auto it = s_signalObjectMap.begin(); it != s_signalObjectMap.end(); it++)
    {
        qDebug() << "key:" << it.key() << ",value:" << it.value();
    }
    qDebug() << "s_slotObjectMap:";
    for (auto it = s_slotObjectMap.begin(); it != s_slotObjectMap.end(); it++)
    {
        qDebug() << "key:" << it.key() << ",value:" << it.value();
    }
}

在我的场景里我想将mainWindow的OpenGLWidget发送的【信号】连接到mainWindow的tabView(我自己定义的一个继承自QWidget的类)的SimSettingWidget(也是我自己定义的一个继承自QWidget的类)的一个lineEdit_Fps控件【】显示我的帧率,首先先统一插入到静态的Slot哈希表,这写在SimSettingWidget的构造函数里

SimSettingWidget::SimSettingWidget(QWidget *parent) : QWidget(parent),
                                                      ui(new Ui::SimSettingWidget)
{
    ui->setupUi(this);
    SignalSlotObjectMap::InsertSlotObjectMap("lineEditFps", static_cast<void *>(ui->lineEdit_Fps));
}

这样mainWindow里把这个指针取出来就行了:


MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
                                          ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 其他程序
    QLineEdit *lineEditFps = static_cast<QLineEdit *>(SignalSlotObjectMap::FindSlotObjectMap("lineEditFps"));
    connect(ui->widget_robotSim, &RobotView::sendFPS, this, [lineEditFps](float currentFPS)
            { lineEditFps->setText(QString("%1").arg(currentFPS)); });
}

这样就统一管理的需要的控件,所有的connect都可以在mainWindow进行,相当于树的根节点,表除了可以插入信号控件的指针,也可以插入槽控件的指针,写起来就比较舒服了。

相关文章:

  • 数字化工厂人员定位系统方案之高危场景人员聚集预警系统架构设计(二)
  • Redis大Key问题全解析:从原理到实战的深度解决方案
  • MyBatis一对多查询方式
  • 什么是AI?AI能对我们生活产生哪些影响?
  • 基于Python的端口扫描器和目录扫描工具实现方案,结合机器学习进行指纹识别
  • Kubernetes学习笔记-IDEA开发工具本地调试
  • 离线服务器ollama新增qwen2:0.5b模型
  • 从零手工撸写个人工神经元网络(解决异或问题)Python+c++结构化
  • 江科大51单片机笔记【14】LCD1602(上)
  • 操作系统知识点27
  • 双 Token 无感刷新机制在前后端分离架构中实现
  • 【计量地理学】实验三 地理数据的基本统计分析
  • Unity使用自定义类的List在Inspector面板上显示异常(2021.3.4)
  • Appium等待机制--强制等待、隐式等待、显式等待
  • 工具(十二):Java导出MySQL数据库表结构信息到excel
  • 使用DeepSeek完成一个简单嵌入式开发
  • Apache Tomcat漏洞,对其进行升级
  • 前端及后端实现csv文件下载功能
  • 鸿蒙Next开发与实战经验总结
  • MicroPython 智能硬件开发完整指南
  • 合肥高端网站建设公司/seo1搬到哪里去了
  • 深圳做网站建设/上海b2b网络推广外包
  • 长沙如何做百度的网站/seo课程哪个好
  • 类似站酷的设计类网站/无代码免费web开发平台
  • 商业网站建设常识/网时代教育培训机构怎么样
  • 定制程序网站/网站权重一般有几个等级