0


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

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

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

文章目录

主界面工程为

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#pragmaonce#include<QtWidgets/QMainWindow>#include"ui_A.h"classA:publicQMainWindow{
    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#pragmaonce#include<QtWidgets/QMainWindow>#include"ui_A.h"#include"test.h"// new codeclassA:publicQMainWindow{
    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_test

c_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_test

c_test

类对象

p_ui

成员变量。根据代码可以看到,

mc_test

对象具有一个成员变量

p_ui

,用于存储

ui

指针的值。


mc_test.testFun();

:这也是新增的代码行,它调用

c_test

类对象

mc_test

testFun()

成员函数。根据代码的意思,

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#ifndefTEST_H#defineTEST_H#include"ui_A.h"classc_test{public:
    Ui::AClass* p_ui;voidtestFun();};#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

类型,而

textBrowser

Ui::AClass

类中的一个成员。

总结一下,

test.cpp

中的代码通过使用存储在

p_ui

成员变量中的

ui

指针,成功在

A

类的

textBrowser

中插入了一行文本。这样,

c_test

类就可以与

A

类的 UI 组件进行交互。


Ref.

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

本文转载自: https://blog.csdn.net/weixin_36815313/article/details/131799576
版权归原作者 Zhao-Jichao 所有, 如有侵权,请联系我们删除。

“【Visual Studio】Qt 在其他 cpp 文件中调用操作 ui 界面控件”的评论:

还没有评论