QTCreator 的使用
写些与 Qt4 相关的东西
用最新的
QtCreator
选择
GUI
的应用会产生含有如下文件的工程
下面就简单分析下各部分的功能。
.pro 文件是供 qmake 使用的文件,不是本文的重点【不过其实也很简单的】,在此不多赘述。
所以呢,还是从 main 开始,
- #include<QtGui/QApplication>
- #include"mainwindow.h"
- int main( int argc, char *argv[])
- {
- QApplicationa(argc,argv);
- MainWindoww;
- w.show();
- return a.exec();
- }
很简单 的样子
QApplication a(argc, argv) 和a.exec() 可以理解为载入了Qt 的架构,跑Qt 的程序都要有此部,就不多说了。
其中调用了个MainWindow 并 把它show 了出来,具体分析下
下面是mainwindow.h 中 的内容
- #ifndefMAINWINDOW_H
- #defineMAINWINDOW_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
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
开始的namespace Ui 可能让人有点摸不着头脑,这是因为qt 把ui 相关的类单独独立了出来,但类名相同,禁用namespace 区 别【但是就目前的使用来说,感觉这样做不怎么好,后面我会解释原因】
声 明namespace Ui 是因为要调用Ui 中 的MainWindow ,此MainWindow 非 彼MainWindow ,后面涉及的*ui 指 针会调用它!
关于Q_OBJECT 就不说了,Qt 中与signal 和slot 相关的类都要这么声明下。
仔细看出了构造,析构就没啥了,只 有那么个*ui !不过现在如果运行下,也只会生成个窗体而已。
下面来看构造函数和析构函数,其实 也就是mainwindow.c
- #include"mainwindow.h"
- #include"ui_mainwindow.h"
- MainWindow::MainWindow(QWidget*parent)
- :QMainWindow(parent),ui(new Ui::MainWindow)
- {
- ui->setupUi(this );
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
构 造 时 在堆 上new 了个Ui 域中的MainWindow ,并调用setupUi ,析构仅仅 是将其delete 了,还是很简单!
正如前面所述Qt 很好的把ui 分离了出去,前面图中的那个.ui 文件就是让QtDesigner 使的布局用文 件!
现在运行下,会生成ui_mainwindow.h ,这个里面会涉及到真正布局用的函数,也就是那个Ui 域中的MainWindow. 下面具体看一下,
- #ifndefUI_MAINWINDOW_H
- #defineUI_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{};
- }//namespaceUi
- QT_END_NAMESPACE
- #endif//UI_MAINWINDOW_H
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
吼吼,一下子多了不少, 但其实还是很容易的。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 中的构件命名,具体也不在此多说。
最后还是看看这段代码
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 后可能还要重新修 改。