日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt中Ui名字空间以及setupUi函数的原理和实现

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt中Ui名字空间以及setupUi函数的原理和实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Qt中Ui名字空間以及setupUi函數的原理和實現

分類: Qt GUI 10514人閱讀 評論(4) 收藏 舉報 uiqtsignalclassdelete

用最新的QtCreator選擇GUI的應用會產生含有如下文件的工程


?

下面就簡單分析下各部分的功能。

?

.pro文件是供qmake使用的文件,不是本文的重點【不過其實也很簡單的】,在此不多贅述。

所以呢,還是從main開始,

[cpp] view plaincopyprint?
  • #include?<QtGui/QApplication>??
  • #include?"mainwindow.h"??
  • int?main(int?argc,?char?*argv[])??
  • {??
  • QApplication?a(argc,?argv);??
  • MainWindow?w;??
  • w.show();??
  • return?a.exec();??
  • }??

  • 很簡單的樣子

    QApplication a(argc, argv)和a.exec()可以理解為載入了Qt的架構,跑Qt的程序都要有此部,就不多說了。

    其中調用了個MainWindow并把它show了出來,具體分析下

    下面是mainwindow.h中的內容

    [cpp] view plaincopyprint?
  • #ifndef?MAINWINDOW_H??
  • #define?MAINWINDOW_H??
  • #include?<QtGui/QMainWindow>??
  • namespace?Ui??
  • {??
  • class?MainWindow;??
  • }??
  • class?MainWindow?:?public?QMainWindow??
  • {??
  • Q_OBJECT??
  • public:??
  • MainWindow(QWidget?*parent?=?0);??
  • ~MainWindow();??
  • private:??
  • Ui::MainWindow?*ui;??
  • };??
  • #endif?//?MAINWINDOW_H??

  • 開始的namespace Ui可能讓人有點摸不著頭腦,這是因為qt把ui相關的類單獨獨立了出來,但類名相同,禁用namespace區別【但是就目前的使用來說,感覺這樣做不怎么好,后面我會解釋原因】

    ?

    聲明namespace Ui是因為要調用Ui中的MainWindow,此MainWindow非彼MainWindow,后面涉及的*ui指針會調用它!

    ?

    關于Q_OBJECT就不說了,Qt中與signal和slot相關的類都要這么聲明下。

    ?

    仔細看出了構造,析構就沒啥了,只有那么個*ui!不過現在如果運行下,也只會生成個窗體而已。

    ?

    下面來看構造函數和析構函數,其實也就是mainwindow.c

    [cpp] view plaincopyprint?
  • #include?"mainwindow.h"??
  • #include?"ui_mainwindow.h"??
  • MainWindow::MainWindow(QWidget?*parent)??
  • :?QMainWindow(parent),?ui(new?Ui::MainWindow)??
  • {??
  • ui->setupUi(this);??
  • }??
  • MainWindow::~MainWindow()??
  • {??
  • delete?ui;??
  • }??

  • 構造時在堆上new了個Ui域中的MainWindow,并調用setupUi,析構僅僅是將其delete了,還是很簡單!

    ?

    正如前面所述Qt很好的把ui分離了出去,前面圖中的那個.ui文件就是讓QtDesigner使的布局用文件!

    ?

    現在運行下,會生成ui_mainwindow.h,這個里面會涉及到真正布局用的函數,也就是那個Ui域中的MainWindow.下面具體看一下,

    [cpp] view plaincopyprint?
  • #ifndef?UI_MAINWINDOW_H??
  • #define?UI_MAINWINDOW_H??
  • #include?<QtCore/QVariant>??
  • #include?<QtGui/QAction>??
  • #include?<QtGui/QApplication>??
  • #include?<QtGui/QButtonGroup>??
  • #include?<QtGui/QHeaderView>??
  • #include?<QtGui/QMainWindow>??
  • #include?<QtGui/QMenuBar>??
  • #include?<QtGui/QStatusBar>??
  • #include?<QtGui/QToolBar>??
  • #include?<QtGui/QWidget>??
  • QT_BEGIN_NAMESPACE??
  • class?Ui_MainWindow??
  • {??
  • public:??
  • QMenuBar?*menuBar;??
  • QToolBar?*mainToolBar;??
  • QWidget?*centralWidget;??
  • QStatusBar?*statusBar;??
  • void?setupUi(QMainWindow?*MainWindow)??
  • {??
  • if?(MainWindow->objectName().isEmpty())??
  • MainWindow->setObjectName(QString::fromUtf8("MainWindow"));??
  • MainWindow->resize(600,?400);??
  • menuBar?=?new?QMenuBar(MainWindow);??
  • menuBar->setObjectName(QString::fromUtf8("menuBar"));??
  • MainWindow->setMenuBar(menuBar);??
  • mainToolBar?=?new?QToolBar(MainWindow);??
  • mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));??
  • MainWindow->addToolBar(mainToolBar);??
  • centralWidget?=?new?QWidget(MainWindow);??
  • centralWidget->setObjectName(QString::fromUtf8("centralWidget"));??
  • MainWindow->setCentralWidget(centralWidget);??
  • statusBar?=?new?QStatusBar(MainWindow);??
  • statusBar->setObjectName(QString::fromUtf8("statusBar"));??
  • MainWindow->setStatusBar(statusBar);??
  • retranslateUi(MainWindow);??
  • QMetaObject::connectSlotsByName(MainWindow);??
  • }?//?setupUi??
  • void?retranslateUi(QMainWindow?*MainWindow)??
  • {??
  • MainWindow->setWindowTitle(QApplication::translate("MainWindow",?"MainWindow",?0,?QApplication::UnicodeUTF8));??
  • Q_UNUSED(MainWindow);??
  • }?//?retranslateUi??
  • };??
  • namespace?Ui?{??
  • class?MainWindow:?public?Ui_MainWindow?{};??
  • }?//?namespace?Ui??
  • QT_END_NAMESPACE??
  • #endif?//?UI_MAINWINDOW_H??
  • 吼吼,一下子多了不少,但其實還是很容易的。Ui_MainWindow聲明了幾個構件,具體我就不說了,因為也沒啥可說的,它實現了setupUi函式,也就是前面那個MainWindow中調用的setupUi。

    但是要說明的是QMetaObject::connectSlotsByName函式會自動連接相應名稱的信號與槽,但要注意它連接的是傳入的MainWindow及其子構件【不是子類】,注意前邊ui->setupUi(this)中傳入的this,也就是非ui域中的MainWindow,所以如果要聲明signal和slot時還是要在非ui域的MainWindow中來聲明,然后通過ui->xxx的形式來與GUI產生交互!如果我們在QtDesiner中拖放一個按鈕然后點擊go to slot就很容易印證這一點。

    retranslateUi則會為ui中的構件命名,具體也不在此多說。

    最后還是看看這段代碼

    [cpp] view plaincopyprint?
  • namespace?Ui?{??
  • ??
  • class?MainWindow:?public?Ui_MainWindow?{};??
  • ??
  • }?//?namespace?Ui??

  • 前面非Ui域中的MainWindow的*ui指向的是Ui域中的MainWindow,而Ui域中的MainWindow出了繼承了Ui_MainWindow之外,內部一貧如洗!【有點繞口了】

    來張圖片,再復習下

    ?

    最后要說明的有兩點,個人感覺是QtCreator的BUG,

    其一是如果自己定制控件,并且想在內置的designer中載入,win下用mingw是不可行的,因為sdk套件中的designer是用微軟的編譯器編譯的,當然也有個比較方便的解決的辦法,就是把qtcreator的源碼下來,用現有的creator再編譯一遍,然后覆蓋過去就行了。

    其二也是前面提到的,兩個同名的MainWindow僅用Ui域來區分,雖然感覺這樣做從設計上來說是很美的,但調試時卻會有些許的問題,總之在creator中調試不能識別正確的域,具體見下圖例


    ?

    像上面這張圖this實際上應該指向的是Ui域中的MainWindow【this其實指向的是MainWindow,它并不知是哪個域的MainWindow,再往下展開就錯誤的指向了Ui域】,但調試的數據區指向了Ui域中的MainWindow,當然也不是沒有解決的辦法,你可以手工將Ui域中的MainWindow改下名就可以獲得正確的調試信息了,只是這樣做稍顯麻煩,而且再度運行qmake后可能還要重新修改。

    總結

    以上是生活随笔為你收集整理的Qt中Ui名字空间以及setupUi函数的原理和实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。