【Visual Studio】Qt 在其他 cpp 文件中调用操作 ui 界面控件

news2024/12/26 20:58:17

知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。

还整了一个如何相互之间调用函数的文章,感兴趣可以看:【Visual Studio】Qt 在其他 cpp 文件中调用主工程下文件中的函数。

文章目录

  • 创建一个原始工程名字为 `A`
    • `A.ui`
    • `A.h`
    • `A.cpp`
  • 修改后
    • `A.h`
    • `A.cpp`
    • `test.h`
    • `test.cpp`
  • Ref.

主界面工程为 A,添加的文件名字为 test,目标是在 test 文件里操作 A 工程里的 ui 控件。


简洁版直接看这个截图就行,大意就是将老的实例化 ui 变成指针,将地址传递给 p_ui,然后通过调用 p_ui 来间接调用 ui

名称解释:

  • c_test 表示新建的类
  • p_ui 表示新建的类里的指针类型的成员变量
  • testFun() 表示新建的类的函数
  • mc_test 实例化的类,用来调用新建的 c_test 的类

在这里插入图片描述


详细版可以看下边这些。

创建一个原始工程名字为 A

为了更好地演示,首先创建一个原始工程,名字为 A,并打印一段文字。效果如下图所示:

在这里插入图片描述


工程的四个项目文件分别如下:

A.ui

在这里插入图片描述


A.h

// A.h
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_A.h"

class A : public QMainWindow
{
    Q_OBJECT

public:
    A(QWidget *parent = nullptr);
    ~A();

private:
    Ui::AClass ui;
};

类定义:class A : public QMainWindow 指示 A 类是一个继承自 Qt 的主窗口类 QMainWindow 的类。通过继承,A 类获得了 QMainWindow 的功能,并可以在其基础上进行扩展。

Q_OBJECT: 这是一个宏,用于启用 Qt 的元对象系统(Meta-Object System,MOC)。元对象系统是 Qt 中一种用于实现信号与槽机制,反射和其他元编程功能的机制。为了使用这些功能,类必须包含 Q_OBJECT 宏。


构造函数:A(QWidget *parent = nullptr);A 类的构造函数。构造函数在创建类的实例时被调用。它的参数 QWidget *parent 表示构造函数的父类,这里设置为 nullptr,表示没有父类。

析构函数:~A();A 类的析构函数。析构函数在类的实例被销毁时被调用。在析构函数中,通常进行资源的释放和清理工作。


私有成员变量:Ui::AClass ui; 是一个私有成员变量,它是通过 UI 文件自动生成的用户界面类的实例。通过这个变量,您可以访问和操作 UI 文件中定义的组件和布局。

双冒号 :: 表示作用域解析运算符(Scope Resolution Operator)。它有两个主要的用途:

  1. 命名空间成员的访问:在 C++ 中,可以使用命名空间将一组相关的类、函数、变量等封装在一起。双冒号 :: 用于访问命名空间中的成员。在代码中,Ui::AClass 中的 Ui 表示一个命名空间,AClass 则是在 Ui 命名空间中定义的一个类。因此,Ui::AClass 表示访问位于 Ui 命名空间中的 AClass 类。
  2. 静态成员的访问:在类中,可以定义静态成员(Static Members),这些成员属于类本身,而不是类的实例。双冒号 :: 用于访问类的静态成员。在代码中,Ui::AClass 中的 Ui 表示一个命名空间或类,而 AClass 则是在这个命名空间或类中定义的一个静态成员。因此,Ui::AClass 表示访问类 Ui 中的静态成员 AClass

在上述代码中,Ui::AClass 表示访问命名空间或类 Ui 中的类 AClass。这个类是通过 Qt 设计师生成的,用于描述与窗体 A 相关联的用户界面。

总结来说,双冒号 :: 用于在 C++ 中访问命名空间中的成员或类的静态成员,帮助准确定位所需的符号,避免命名冲突,并使代码更加清晰和模块化。
在这里插入图片描述

Ui::AClass 表示一个名为 AClass 的用户界面类。它是通过 Qt 的用户界面设计器创建的类,用于描述窗体的布局和组件。通常,当你使用 Qt 设计师(Qt Designer)创建一个用户界面时,它会生成一个对应的头文件(通常以 .h 为扩展名),其中包含了一个名为 Ui::ClassName 的类。ClassName 是你在设计师中指定的窗体的类名,可以是你创建的窗体的名称或其他自定义名称。在上述示例代码中,Ui::AClass 表示在 Qt 设计师中创建的与窗体 A 相关联的用户界面类。它描述了 A 窗体的布局和组件,包括在设计师中创建的各种控件(如按钮、标签、文本框等)的属性和布局信息。

#include "ui_A.h"

Ui::AClass 是通过包含名为 ui_A.h 的头文件来定义的。在这个头文件中,Qt 设计师自动生成了与 A 窗体相关的用户界面类的声明和定义。通过包含 ui_A.h 头文件,你可以在 A 类中创建一个名为 ui 的对象,它是 Ui::AClass 类的一个实例。通过这个 ui 对象,你可以访问并操作在设计师中创建的窗体组件。

例如,你可以使用 ui 对象来设置窗体中的控件的属性,或在代码中对控件进行操作。例如,如果你在设计师中创建了一个名为 pushButton 的按钮控件,你可以使用 ui.pushButton 来访问和操作该按钮控件。

总的来说,Ui::AClass 是一个自动生成的用户界面类,它用于描述与窗体 A 相关联的用户界面,并通过 ui 对象提供对窗体组件的访问和操作。这种分离窗体逻辑与用户界面描述的设计方式,使得代码更加模块化和易于维护。


A.cpp

// A.cpp
#include "A.h"

A::A(QWidget *parent) : QMainWindow(parent)
{
    ui.setupUi(this);

    ui.textBrowser->insertPlainText("This is a text from A.cpp!\n");
}

A::~A()
{}

这段代码定义了类 A 的构造函数和析构函数的实现,其中在构造函数中通过 ui.setupUi(this); 将用户界面与窗体关联。

A::A(QWidget *parent) : QMainWindow(parent):这是类 A 的构造函数的实现部分。在构造函数中,首先调用了父类 QMainWindow 的构造函数,使用 parent 参数来初始化基类。

接着,通过 ui.setupUi(this); 调用了 ui 对象的 setupUi 函数,将 ui 对象与当前的窗体对象 this(即类 A 的实例)关联起来。这样,ui 对象就可以用来访问与窗体 A 相关联的用户界面组件。

A::~A():这是类 A 的析构函数的实现部分。析构函数在对象被销毁时自动调用,用于释放对象的资源。在这里,析构函数不做任何额外的操作,因为没有需要手动释放的资源。

至于为什么是 A::A(QWidget *parent),而不是 A:A(QWidget *parent)
这是因为对于 C++ 中的构造函数和析构函数,正确的语法是使用两个冒号 :: 来指明函数所属的类,而不是一个冒号 :。这是C++中的命名空间解析操作符(scope resolution operator)。所以,在构造函数的定义中,应该是 A::A() 而不是 A:A()。同样,析构函数的定义应该是 A::~A() 而不是 A:~A()
在这里,A:: 表示 A 类中的成员函数,A(QWidget *parent) 表示构造函数的名称,~A() 表示析构函数的名称。函数名前面的 A:: 是用来限定这些函数是属于 A 类的。
如果在构造函数或析构函数的定义中使用了错误的语法(例如 A:A()A:~A()),编译器会报错并指出无法找到匹配的函数声明。


修改后

接下来将创建一个 test.h 和一个 test.cpp 文件,并实现在 test.cpp 中调用 ui 中的控件 textBrowser,并打印出来一段文字标记来自 test.cpp。最终效果如下图所示:

在这里插入图片描述


A.h

// A.h
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_A.h"

#include "test.h"       // new code

class A : public QMainWindow
{
    Q_OBJECT

public:
    A(QWidget *parent = nullptr);
    ~A();

private:
    Ui::AClass *ui;     // change code
    c_test mc_test;     // new code
};


修改后的 A.h 相较于之前的,添加了 #include "test.h",这是一个预处理指令,用于包含名为 test.h 的头文件。这意味着您在 A.h 中引入了 test.h 文件中定义的内容,可能是另一个自定义类或者功能模块。我们这里属于引入了自定义类 test


Ui::AClass *ui;:这是类 A 的一个私有成员变量的修改。原来的代码中使用的是 Ui::AClass ui;,表示 ui 是一个 Ui::AClass 类型的对象。而在这个修改后的代码中,使用了 Ui::AClass *ui;,表示 ui 是一个 Ui::AClass 类型的指针。这个修改是为了在类 A 中使用指针来管理 ui 对象的生命周期和资源释放,方便咱们在 test.h 中访问。


c_test mc_test;:这是一个新的类成员变量,它是通过 test.h 头文件定义的 c_test 类的实例。现在在 A 类中拥有一个名为 mc_testc_test 类对象。mc_test 可以用来访问和操作 c_test 类中的成员。


这些变化是希望在 A 类中使用名为 c_test 的自定义类,并且想要通过指针动态地管理 ui 成员变量。


A.cpp

// A.cpp
#include "A.h"

A::A(QWidget *parent) : QMainWindow(parent)
{
    ui->setupUi(this);

    ui->textBrowser->insertPlainText("This is a text from A.cpp!\n");

    mc_test.p_ui = ui;      // new code
    mc_test.testFun();      // new code
}

A::~A()
{}


mc_test.p_ui = ui;:这是新添加的代码行,它将 ui 指针赋值给名为 mc_testc_test 类对象 p_ui 成员变量。根据代码可以看到,mc_test 对象具有一个成员变量 p_ui,用于存储 ui 指针的值。


mc_test.testFun();:这也是新增的代码行,它调用 c_test 类对象 mc_testtestFun() 成员函数。根据代码的意思,testFun() 函数是 c_test 类中的一个成员函数,根据函数定义(看 test.cpp 文件)也可以知道,它利用了存储在 p_ui 成员变量中的 ui 指针,以实现与 UI 相关的功能。


需要注意的是,因为对 A.h 进行了修改,将 ui 成员变量从对象变为了指针。因此,在 A.cpp 中使用 ui 时,需要使用 ui-> 来访问其成员,而不再是 ui.,例如 ui->setupUi(this)ui->textBrowser->insertPlainText("This is a text from A.cpp!\n")


test.h

// test.h
#ifndef TEST_H
#define TEST_H

#include "ui_A.h"	

class c_test
{
public:
	Ui::AClass* p_ui;	

	void testFun();
};

#endif

#include "ui_A.h:这一行包含名为 ui_A.h 的头文件,它是通过 Qt 的 UI 设计器从 A.ui 生成的头文件。这个头文件中包含了 UI 文件中定义的类和组件。


Ui::AClass* p_ui;:这是 c_test 类的成员变量,它是一个指向 Ui::AClass 类型的指针。根据之前的代码,Ui::AClass 是通过 UI 文件生成的用户界面类,而 p_ui 指针将用于存储 A 类中的 ui 指针,以便在 c_test 类中访问和操作 A 类的UI组件。


void testFun();:这是 c_test 类的成员函数声明。根据之前在 A.cpp 中的调用 mc_test.testFun(),这个函数被用于实现一些与 UI 相关的功能,使用了存储在 p_ui 成员变量中的 ui 指针。


现在,可以在 test.cpp 中实现 test.h 中声明的成员函数,以及根据需要与ui进行交互。


test.cpp

// test.cpp
#include "test.h"

void c_test::testFun()
{
	p_ui->textBrowser->insertPlainText("This is a text from test.cpp!\n");
}


#include "test.h":这是包含 test.h 头文件,这样就可以访问 test 类的声明和成员函数定义。

void c_test::testFun():这是 c_test 类的成员函数 testFun() 的实现。根据代码的内容,这个函数将在 A 类的 UI 组件 textBrowser 中插入一行文本。这里的实现通过使用 p_ui 成员变量来访问 A 类中的 ui 指针,因为 p_ui 指向 Ui::AClass 类型,而 textBrowserUi::AClass 类中的一个成员。

总结一下,test.cpp 中的代码通过使用存储在 p_ui 成员变量中的 ui 指针,成功在 A 类的 textBrowser 中插入了一行文本。这样,c_test 类就可以与 A 类的 UI 组件进行交互。


Ref.

  1. Qt中,在另一cpp文件操作ui界面的相关控件
  2. [Qt] [UI] 多个类中操作同一个UI界面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/777404.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第四章:包围体

第四章&#xff1a;包围体 引言-包围体&#xff08;1&#xff09;包围体测试和几何体测试&#xff08;2&#xff09;包围体测试的代价和作用&#xff08;3&#xff09;相交测试的优化&#xff08;4&#xff09;包围体相关章节和主旨 一、BV 期望特征1.1 有效的包围体1.2 包围体…

docker 网络配置详解

目录 1、docker网络模式 2、容器和容器之间是如何互通 3、容器之间互通 --link 3、自定义网络 4、不通网段的容器进行网络互通 1、docker网络模式 docker 网络模式采用的是桥接模式&#xff0c;当我们创建了一个容器后docker网络就会帮我们创建一个虚拟网卡&#xff0c;这…

Electron 学习_在进程之间通信

1.问题&#xff1a;Electron的主进程和渲染进程有着清楚的分工&#xff0c;并且不可互换。从渲染进程直接访问Node.js 接口&#xff0c;亦或者 从主进程访问HTML文档对象模型(DOM)都是不可能的 2.解决方法&#xff1a;使用进程间通信 (IPC) 可以使用 Electron 的ipcMain 模块和…

Redisson限流器RRateLimiter使用及源码分析

一、使用 使用很简单、如下 // 1、 声明一个限流器 RRateLimiter rateLimiter redissonClient.getRateLimiter(key);// 2、 设置速率&#xff0c;5秒中产生3个令牌 rateLimiter.trySetRate(RateType.OVERALL, 3, 5, RateIntervalUnit.SECONDS);// 3、试图获取一个令牌&#…

TCP首部格式【TCP原理(笔记五)】

文章目录 TCP首部格式源端口号&#xff08;Source Port&#xff09;目标端口号&#xff08;Destination Port&#xff09;序列号&#xff08;Sequence Number&#xff09;确认应答号&#xff08;Acknowledgement Number&#xff09;数据偏移&#xff08;Data Offset&#xff09…

Oracle 普通视图 (Oracle Standard Views)

视图&#xff08;views&#xff09;是一种基于表的"逻辑抽象"对象&#xff0c;由于它是从表衍生出来的&#xff0c;因此和表有许多相同点&#xff0c;我们可以和对待表一样对其进行查询/更新操作。但视图本身并不存储数据&#xff0c;也不分配存储空间。 本文只讨论普…

Linux下搭建pyqt5开发环境—基于Pycharm

防踩坑Tips&#xff1a; 1、不能学windows那样直接用pip安装PyQt5Designer和pyqt5-tools。这两个模块最根本的是用的windows的程序&#xff0c;linux上是运行不了的&#xff0c;特别是PyQt5Designer&#xff0c;会提示安装失败。 2、推荐在python环境安装同系统版本一致的pyq…

2023.7.16 第五十九次周报

目录 前言 文献阅读:跨多个时空尺度进行预测的时空 LSTM 模型 背景 本文思路 本文解决的问题 方法论 SPATIAL 自动机器学习模型 数据处理 模型性能 代码 用Python编写的LSTM多变量预测模型 总结 前言 This week, I studied an article that uses LSTM to solve p…

数据分析系统中的六边形战士——奥威BI系统

数据分析软件可以对收集的数据进行分析和报告&#xff0c;帮助企业获得更深入的数据洞察力&#xff0c;从而推动企业数字化运营决策&#xff0c;提高决策效率与质量。进入大数据时代&#xff0c;企业对数据分析软件的要求也在水涨船高&#xff0c;传统的数据分析软件显然已不能…

数据结构 单向链表(不循环)的基础知识和基础操作

头定义&#xff1a; typedef int datatype; typedef struct Node {//数据域存储数据datatype data;//指针域存储下一个地址struct Node *next; }*Linkelist; 创建节点 Linkelist create_node()//创建新节点 {Linkelist node(Linkelist)malloc(sizeof(struct Node));if(nodeN…

Elasticsearch 源码探究 001——故障探测和恢复机制

1、Elasticsearch 故障探测及熔断背景 探究Elasticsearch7.10.2 节点之间的故障探测以及熔断故障是怎么做的&#xff0c;思考生产上的最佳实践。 服务端故障场景&#xff1a; 单个master挂掉 除了断点断网&#xff0c;状态同步异常&#xff0c;主master也会认为自己已经失败&am…

ASPICE V模型之软件需求

ASPICE V模型之软件需求 了解ASPICE认识软件需求软件需求分解软件需求工作流程 了解ASPICE ASPICE全称是“Automotive Software Process Improvement and Capacity Determination”汽车软件过程改进及能力评定&#xff0c;是汽车行业用于评价软件开发团队的研发能力水平的模型框…

全球生成式AI大竞赛,Llama 2大模型现已可在亚马逊云科技上使用

一直以来Llama可以说是AI社区内最强大的开源大模型。但因为开源协议问题&#xff0c;一直不可免费商用。7月19日&#xff0c;Meta发布了大家期待已久的免费可商用版本Llama 2。一夜之间&#xff0c;大模型格局再次发生巨变。 作为Meta宣布的首批合作伙伴之一&#xff0c;现亚…

Ubuntu 安装Postgresql与PostGIS

1.前言 最近在做GIS分析&#xff0c;采集设备的经纬度点判断是否进出围栏以及是否产生道路偏移报警&#xff0c;在之前的文章有介绍过Windows下使用C#来实现&#xff0c;参考文章&#xff1a;利用PostgresqlPostgis进行空间地理信息分析&#xff08;道路偏移&#xff0c;进出电…

sql注入---报错注入

updatexml&#xff08;&#xff09;&#xff1a;对XML文档数据进行查询和修改 extractvalue&#xff08;&#xff09;&#xff1a;对XML文档数据进行查询 floor&#xff08;&#xff09;&#xff1a;取整的函数 前提是未关闭数据库报错函数&#xff0c;对于一些SQL语句的错误…

Java反射、动态代理

文章目录 反射什么是动态代理&#xff1f;程序为什么需要代理?代理长什么样? 反射 java反射机制原理&#xff1a;我们写的源代码是.java文件&#xff0c;通过javac编译后成为.class文件&#xff0c;即字节码文件&#xff0c;程序执行时&#xff0c;JVM会类加载字节码文件到内…

浅谈单片机

目录 1.什么是单片机 2.单片机的作用&#xff1f; 3.单片机的种类 4.如何学好单片机 5. 单片机的就业前景 1.什么是单片机 单片机&#xff08;Microcontroller Unit&#xff0c;简称MCU&#xff09;是一种集成了微处理器核心、存储器、输入输出端口和各种外围功能模块于一体…

Rspack 学习了解

一、简介 Rspack GitHub 仓库、Rspack Quick start。 Rspack 是由字节 ByteDance Web Infra 团队基于 Rust 语言开发的 Web 高性能构建工具。 Rust 是种高效、可靠的通用高级语言。其高效不仅限于开发效率&#xff0c;执行效率也是令人称赞的&#xff0c;属于少有兼顾开发效率…

vulnhub打靶--buli_b0x

目录 vulnhub--buli_b0x1.下载靶机2.导入靶机&#xff0c;开启靶机&#xff0c;nmap扫描3.探测目录&#xff0c;发现敏感目录4.通过test.php下载源码5.代码审计6.提权7.总结 vulnhub–buli_b0x 1.下载靶机 Billu_b0x.zip 2.导入靶机&#xff0c;开启靶机&#xff0c;nmap扫描…

分布式 RPC 框架HSF

分布式 RPC 框架HSF 概述HSF架构调用方式优势应用场景 概述 HSF (High-speed Service Framework)&#xff0c;高速服务框架&#xff0c;是在阿里巴巴内部广泛使用的分布式 RPC 服务框架。HSF 作为阿里巴巴的基础中间件&#xff0c;联通不同的业务系统&#xff0c;解耦系统间的…