知識(shí)不是單獨(dú)的,一定是成體系的。更多我的個(gè)人總結(jié)和相關(guān)經(jīng)驗(yàn)可查閱這個(gè)專(zhuān)欄:Visual Studio。
還整了一個(gè)如何相互之間調(diào)用函數(shù)的文章,感興趣可以看:【Visual Studio】Qt 在其他 cpp 文件中調(diào)用主工程下文件中的函數(shù)。
主界面工程為 A
,添加的文件名字為 test
,目標(biāo)是在 test
文件里操作 A
工程里的 ui
控件。
簡(jiǎn)潔版直接看這個(gè)截圖就行,大意就是將老的實(shí)例化 ui
變成指針,將地址傳遞給 p_ui
,然后通過(guò)調(diào)用 p_ui
來(lái)間接調(diào)用 ui
。
名稱(chēng)解釋?zhuān)?/p>
-
c_test
表示新建的類(lèi) -
p_ui
表示新建的類(lèi)里的指針類(lèi)型的成員變量 -
testFun()
表示新建的類(lèi)的函數(shù) -
mc_test
實(shí)例化的類(lèi),用來(lái)調(diào)用新建的c_test
的類(lèi)
詳細(xì)版可以看下邊這些。
創(chuàng)建一個(gè)原始工程名字為 A
為了更好地演示,首先創(chuàng)建一個(gè)原始工程,名字為 A
,并打印一段文字。效果如下圖所示:
工程的四個(gè)項(xiàng)目文件分別如下:
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;
};
類(lèi)定義:class A : public QMainWindow
指示 A
類(lèi)是一個(gè)繼承自 Qt 的主窗口類(lèi) QMainWindow
的類(lèi)。通過(guò)繼承,A
類(lèi)獲得了 QMainWindow
的功能,并可以在其基礎(chǔ)上進(jìn)行擴(kuò)展。
Q_OBJECT
: 這是一個(gè)宏,用于啟用 Qt 的元對(duì)象系統(tǒng)(Meta-Object System,MOC)。元對(duì)象系統(tǒng)是 Qt 中一種用于實(shí)現(xiàn)信號(hào)與槽機(jī)制,反射和其他元編程功能的機(jī)制。為了使用這些功能,類(lèi)必須包含 Q_OBJECT 宏。
構(gòu)造函數(shù):A(QWidget *parent = nullptr);
是 A
類(lèi)的構(gòu)造函數(shù)。構(gòu)造函數(shù)在創(chuàng)建類(lèi)的實(shí)例時(shí)被調(diào)用。它的參數(shù) QWidget *parent
表示構(gòu)造函數(shù)的父類(lèi),這里設(shè)置為 nullptr
,表示沒(méi)有父類(lèi)。
析構(gòu)函數(shù):~A();
是 A
類(lèi)的析構(gòu)函數(shù)。析構(gòu)函數(shù)在類(lèi)的實(shí)例被銷(xiāo)毀時(shí)被調(diào)用。在析構(gòu)函數(shù)中,通常進(jìn)行資源的釋放和清理工作。
私有成員變量:Ui::AClass ui;
是一個(gè)私有成員變量,它是通過(guò) UI
文件自動(dòng)生成的用戶(hù)界面類(lèi)的實(shí)例。通過(guò)這個(gè)變量,您可以訪問(wèn)和操作 UI
文件中定義的組件和布局。
雙冒號(hào)
::
表示作用域解析運(yùn)算符(Scope Resolution Operator)。它有兩個(gè)主要的用途:
- 命名空間成員的訪問(wèn):在 C++ 中,可以使用命名空間將一組相關(guān)的類(lèi)、函數(shù)、變量等封裝在一起。雙冒號(hào)
::
用于訪問(wèn)命名空間中的成員。在代碼中,Ui::AClass
中的Ui
表示一個(gè)命名空間,AClass
則是在Ui
命名空間中定義的一個(gè)類(lèi)。因此,Ui::AClass
表示訪問(wèn)位于Ui
命名空間中的AClass
類(lèi)。- 靜態(tài)成員的訪問(wèn):在類(lèi)中,可以定義靜態(tài)成員(Static Members),這些成員屬于類(lèi)本身,而不是類(lèi)的實(shí)例。雙冒號(hào)
::
用于訪問(wèn)類(lèi)的靜態(tài)成員。在代碼中,Ui::AClass
中的Ui
表示一個(gè)命名空間或類(lèi),而AClass
則是在這個(gè)命名空間或類(lèi)中定義的一個(gè)靜態(tài)成員。因此,Ui::AClass
表示訪問(wèn)類(lèi)Ui
中的靜態(tài)成員AClass
。在上述代碼中,
Ui::AClass
表示訪問(wèn)命名空間或類(lèi)Ui
中的類(lèi)AClass
。這個(gè)類(lèi)是通過(guò)Qt
設(shè)計(jì)師生成的,用于描述與窗體A
相關(guān)聯(lián)的用戶(hù)界面。總結(jié)來(lái)說(shuō),雙冒號(hào)
::
用于在 C++ 中訪問(wèn)命名空間中的成員或類(lèi)的靜態(tài)成員,幫助準(zhǔn)確定位所需的符號(hào),避免命名沖突,并使代碼更加清晰和模塊化。
Ui::AClass
表示一個(gè)名為 AClass
的用戶(hù)界面類(lèi)。它是通過(guò) Qt 的用戶(hù)界面設(shè)計(jì)器創(chuàng)建的類(lèi),用于描述窗體的布局和組件。通常,當(dāng)你使用 Qt 設(shè)計(jì)師(Qt Designer)創(chuàng)建一個(gè)用戶(hù)界面時(shí),它會(huì)生成一個(gè)對(duì)應(yīng)的頭文件(通常以 .h
為擴(kuò)展名),其中包含了一個(gè)名為 Ui::ClassName
的類(lèi)。ClassName
是你在設(shè)計(jì)師中指定的窗體的類(lèi)名,可以是你創(chuàng)建的窗體的名稱(chēng)或其他自定義名稱(chēng)。在上述示例代碼中,Ui::AClass
表示在 Qt 設(shè)計(jì)師中創(chuàng)建的與窗體 A
相關(guān)聯(lián)的用戶(hù)界面類(lèi)。它描述了 A
窗體的布局和組件,包括在設(shè)計(jì)師中創(chuàng)建的各種控件(如按鈕、標(biāo)簽、文本框等)的屬性和布局信息。
#include "ui_A.h"
Ui::AClass
是通過(guò)包含名為 ui_A.h
的頭文件來(lái)定義的。在這個(gè)頭文件中,Qt 設(shè)計(jì)師自動(dòng)生成了與 A
窗體相關(guān)的用戶(hù)界面類(lèi)的聲明和定義。通過(guò)包含 ui_A.h
頭文件,你可以在 A
類(lèi)中創(chuàng)建一個(gè)名為 ui
的對(duì)象,它是 Ui::AClass
類(lèi)的一個(gè)實(shí)例。通過(guò)這個(gè) ui
對(duì)象,你可以訪問(wèn)并操作在設(shè)計(jì)師中創(chuàng)建的窗體組件。
例如,你可以使用 ui
對(duì)象來(lái)設(shè)置窗體中的控件的屬性,或在代碼中對(duì)控件進(jìn)行操作。例如,如果你在設(shè)計(jì)師中創(chuàng)建了一個(gè)名為 pushButton
的按鈕控件,你可以使用 ui.pushButton
來(lái)訪問(wèn)和操作該按鈕控件。
總的來(lái)說(shuō),Ui::AClass
是一個(gè)自動(dòng)生成的用戶(hù)界面類(lèi),它用于描述與窗體 A
相關(guān)聯(lián)的用戶(hù)界面,并通過(guò) ui
對(duì)象提供對(duì)窗體組件的訪問(wèn)和操作。這種分離窗體邏輯與用戶(hù)界面描述的設(shè)計(jì)方式,使得代碼更加模塊化和易于維護(hù)。
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()
{}
這段代碼定義了類(lèi) A
的構(gòu)造函數(shù)和析構(gòu)函數(shù)的實(shí)現(xiàn),其中在構(gòu)造函數(shù)中通過(guò) ui.setupUi(this);
將用戶(hù)界面與窗體關(guān)聯(lián)。
A::A(QWidget *parent) : QMainWindow(parent)
:這是類(lèi) A
的構(gòu)造函數(shù)的實(shí)現(xiàn)部分。在構(gòu)造函數(shù)中,首先調(diào)用了父類(lèi) QMainWindow
的構(gòu)造函數(shù),使用 parent
參數(shù)來(lái)初始化基類(lèi)。
接著,通過(guò) ui.setupUi(this);
調(diào)用了 ui
對(duì)象的 setupUi
函數(shù),將 ui
對(duì)象與當(dāng)前的窗體對(duì)象 this
(即類(lèi) A
的實(shí)例)關(guān)聯(lián)起來(lái)。這樣,ui
對(duì)象就可以用來(lái)訪問(wèn)與窗體 A
相關(guān)聯(lián)的用戶(hù)界面組件。
A::~A()
:這是類(lèi) A
的析構(gòu)函數(shù)的實(shí)現(xiàn)部分。析構(gòu)函數(shù)在對(duì)象被銷(xiāo)毀時(shí)自動(dòng)調(diào)用,用于釋放對(duì)象的資源。在這里,析構(gòu)函數(shù)不做任何額外的操作,因?yàn)闆](méi)有需要手動(dòng)釋放的資源。
至于為什么是
A::A(QWidget *parent)
,而不是A:A(QWidget *parent)
?
這是因?yàn)閷?duì)于 C++ 中的構(gòu)造函數(shù)和析構(gòu)函數(shù),正確的語(yǔ)法是使用兩個(gè)冒號(hào)::
來(lái)指明函數(shù)所屬的類(lèi),而不是一個(gè)冒號(hào):
。這是C++中的命名空間解析操作符(scope resolution operator)。所以,在構(gòu)造函數(shù)的定義中,應(yīng)該是A::A()
而不是A:A()
。同樣,析構(gòu)函數(shù)的定義應(yīng)該是A::~A()
而不是A:~A()
。
在這里,A::
表示A
類(lèi)中的成員函數(shù),A(QWidget *parent)
表示構(gòu)造函數(shù)的名稱(chēng),~A()
表示析構(gòu)函數(shù)的名稱(chēng)。函數(shù)名前面的A::
是用來(lái)限定這些函數(shù)是屬于A
類(lèi)的。
如果在構(gòu)造函數(shù)或析構(gòu)函數(shù)的定義中使用了錯(cuò)誤的語(yǔ)法(例如A:A()
或A:~A()
),編譯器會(huì)報(bào)錯(cuò)并指出無(wú)法找到匹配的函數(shù)聲明。
修改后
接下來(lái)將創(chuàng)建一個(gè) test.h
和一個(gè) test.cpp
文件,并實(shí)現(xiàn)在 test.cpp
中調(diào)用 ui 中的控件 textBrowser
,并打印出來(lái)一段文字標(biāo)記來(lái)自 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"
,這是一個(gè)預(yù)處理指令,用于包含名為 test.h
的頭文件。這意味著您在 A.h
中引入了 test.h
文件中定義的內(nèi)容,可能是另一個(gè)自定義類(lèi)或者功能模塊。我們這里屬于引入了自定義類(lèi) test
。
Ui::AClass *ui;
:這是類(lèi) A
的一個(gè)私有成員變量的修改。原來(lái)的代碼中使用的是 Ui::AClass ui;
,表示 ui
是一個(gè) Ui::AClass
類(lèi)型的對(duì)象。而在這個(gè)修改后的代碼中,使用了 Ui::AClass *ui
;,表示 ui
是一個(gè) Ui::AClass
類(lèi)型的指針。這個(gè)修改是為了在類(lèi) A
中使用指針來(lái)管理 ui
對(duì)象的生命周期和資源釋放,方便咱們?cè)?test.h
中訪問(wèn)。
c_test mc_test;
:這是一個(gè)新的類(lèi)成員變量,它是通過(guò) test.h
頭文件定義的 c_test
類(lèi)的實(shí)例?,F(xiàn)在在 A
類(lèi)中擁有一個(gè)名為 mc_test
的 c_test
類(lèi)對(duì)象。mc_test
可以用來(lái)訪問(wèn)和操作 c_test
類(lèi)中的成員。
這些變化是希望在 A
類(lèi)中使用名為 c_test
的自定義類(lèi),并且想要通過(guò)指針動(dòng)態(tài)地管理 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
類(lèi)對(duì)象 p_ui
成員變量。根據(jù)代碼可以看到,mc_test
對(duì)象具有一個(gè)成員變量 p_ui
,用于存儲(chǔ) ui
指針的值。
mc_test.testFun();
:這也是新增的代碼行,它調(diào)用 c_test
類(lèi)對(duì)象 mc_test
的 testFun()
成員函數(shù)。根據(jù)代碼的意思,testFun()
函數(shù)是 c_test
類(lèi)中的一個(gè)成員函數(shù),根據(jù)函數(shù)定義(看 test.cpp
文件)也可以知道,它利用了存儲(chǔ)在 p_ui
成員變量中的 ui
指針,以實(shí)現(xiàn)與 UI 相關(guān)的功能。
需要注意的是,因?yàn)閷?duì) A.h
進(jìn)行了修改,將 ui
成員變量從對(duì)象變?yōu)榱酥羔?。因此,?A.cpp
中使用 ui
時(shí),需要使用 ui->
來(lái)訪問(wèn)其成員,而不再是 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
的頭文件,它是通過(guò) Qt 的 UI 設(shè)計(jì)器從 A.ui
生成的頭文件。這個(gè)頭文件中包含了 UI 文件中定義的類(lèi)和組件。
Ui::AClass* p_ui;
:這是 c_test
類(lèi)的成員變量,它是一個(gè)指向 Ui::AClass
類(lèi)型的指針。根據(jù)之前的代碼,Ui::AClass
是通過(guò) UI 文件生成的用戶(hù)界面類(lèi),而 p_ui
指針將用于存儲(chǔ) A
類(lèi)中的 ui
指針,以便在 c_test
類(lèi)中訪問(wèn)和操作 A
類(lèi)的UI組件。
void testFun();
:這是 c_test
類(lèi)的成員函數(shù)聲明。根據(jù)之前在 A.cpp
中的調(diào)用 mc_test.testFun()
,這個(gè)函數(shù)被用于實(shí)現(xiàn)一些與 UI 相關(guān)的功能,使用了存儲(chǔ)在 p_ui
成員變量中的 ui
指針。
現(xiàn)在,可以在 test.cpp
中實(shí)現(xiàn) test.h
中聲明的成員函數(shù),以及根據(jù)需要與ui進(jìn)行交互。
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
頭文件,這樣就可以訪問(wèn) test
類(lèi)的聲明和成員函數(shù)定義。
void c_test::testFun()
:這是 c_test
類(lèi)的成員函數(shù) testFun()
的實(shí)現(xiàn)。根據(jù)代碼的內(nèi)容,這個(gè)函數(shù)將在 A
類(lèi)的 UI 組件 textBrowser
中插入一行文本。這里的實(shí)現(xiàn)通過(guò)使用 p_ui
成員變量來(lái)訪問(wèn) A 類(lèi)中的 ui
指針,因?yàn)?p_ui
指向 Ui::AClass
類(lèi)型,而 textBrowser
是 Ui::AClass
類(lèi)中的一個(gè)成員。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-755262.html
總結(jié)一下,test.cpp
中的代碼通過(guò)使用存儲(chǔ)在 p_ui
成員變量中的 ui
指針,成功在 A
類(lèi)的 textBrowser
中插入了一行文本。這樣,c_test
類(lèi)就可以與 A
類(lèi)的 UI 組件進(jìn)行交互。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-755262.html
Ref.
- Qt中,在另一cpp文件操作ui界面的相關(guān)控件
- [Qt] [UI] 多個(gè)類(lèi)中操作同一個(gè)UI界面
到了這里,關(guān)于【Visual Studio】Qt 在其他 cpp 文件中調(diào)用操作 ui 界面控件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!