先来解释下标题:设计器pk手码……
设计器:是指Qt Designer,就是在Qt开发过程中,部分界面或全部界面采用Designer的拖拽完成,然后功能逻辑通过手敲代码完成,俗称“拖控件”,常见于MFC这类软件设计方式。
手码:就是在Qt开发过程中,不使用Designer,所有界面和功能逻辑都是手敲代码完成,手速快的,看起来比较牛掰。
解释完,突然发现,就这样结束似乎也没什么问题,上面就是二者的区别,还有啥好pk的呢?
pk之前,作者也仿照别人来一个心路历程好了。
读者看过上面的描述,可能会有疑虑:你也没怎么用过Desinger,你哪来勇气要将Designer和手码进行pk,你懂Designer的好吗?
确实,作者后来项目上再也没用过Designer,它的优美和高效作者也没有体会到,作者也怕写这篇文章会被那些Designer控喷……先不管Designer是为了高效和易学易用,还是对标其他语言的“拖控件”,作者不是要诋毁它,或者说不让人去用它,作者想将设计器和手码两种方式做一个梳理和比较,也许能给看到这篇文章的读者一些思路……
关于Qt开发到底该不该用Designer,其实互联网上也有很多声音,大底如下:
上面都是用户使用过程中体会到的两者区别,再来看看官方是怎么说的:
特点如下:
好了,作者试着总结一下这些声音:
暂时先不论这些声音的对错,下面用一个简单的例子看看真实情况是什么样的。
Designer可以设计很复杂的界面,如果一个界面元素太多,可以分拆到不同的ui文件中完成,就是不必在一个ui文件(超级文件)上吊死。
Designer中有那么多控件,一个例子要多复杂才可以把它们拖拽清楚呢?还好,这里不是讲解Designer的使用教程,只需要通过一个小小的例子来探探其中的道道即可。
例子:实现一个窗口类MainWindow,其包含两个QPushButton,一个QLabel,一个QTextBrowser和多个Spacer,两个QPushButton文本分别显示“设计器”和“手码”,用户单击哪个按钮哪方就胜利,同时会改变显示“PK”的QLabel的底色。
主要代码如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
// designer
void MainWindow::on_pushButton_clicked()
{
ui->label->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 255, 0);\n"
"color: rgb(255, 255, 255);"));
}
// manual
void MainWindow::on_pushButton_2_clicked()
{
ui->label->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 255);\n"
"color: rgb(255, 255, 255);"));
}
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.15.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralwidget;
QVBoxLayout *verticalLayout;
QSpacerItem *verticalSpacer_2;
QHBoxLayout *horizontalLayout_2;
QSpacerItem *horizontalSpacer;
QHBoxLayout *horizontalLayout;
QPushButton *pushButton;
QLabel *label;
QPushButton *pushButton_2;
QSpacerItem *horizontalSpacer_2;
QTextBrowser *textBrowser;
QSpacerItem *verticalSpacer;
QMenuBar *menubar;
QStatusBar *statusbar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 600);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
verticalLayout = new QVBoxLayout(centralwidget);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
verticalSpacer_2 = new QSpacerItem(20, 149, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout->addItem(verticalSpacer_2);
horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
horizontalLayout = new QHBoxLayout();
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
pushButton = new QPushButton(centralwidget);
pushButton->setObjectName(QString::fromUtf8("pushButton"));
horizontalLayout->addWidget(pushButton);
label = new QLabel(centralwidget);
label->setObjectName(QString::fromUtf8("label"));
label->setStyleSheet(QString::fromUtf8("background-color: rgb(255, 0, 0);\n"
"color: rgb(255, 255, 255);"));
label->setAlignment(Qt::AlignCenter);
horizontalLayout->addWidget(label);
pushButton_2 = new QPushButton(centralwidget);
pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));
horizontalLayout->addWidget(pushButton_2);
horizontalLayout_2->addLayout(horizontalLayout);
horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer_2);
verticalLayout->addLayout(horizontalLayout_2);
textBrowser = new QTextBrowser(centralwidget);
textBrowser->setObjectName(QString::fromUtf8("textBrowser"));
verticalLayout->addWidget(textBrowser);
verticalSpacer = new QSpacerItem(20, 149, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout->addItem(verticalSpacer);
MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 800, 22));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
pushButton->setText(QCoreApplication::translate("MainWindow", "\350\256\276\350\256\241\345\231\250", nullptr));
label->setText(QCoreApplication::translate("MainWindow", "PK", nullptr));
pushButton_2->setText(QCoreApplication::translate("MainWindow", "\346\211\213\347\240\201", nullptr));
textBrowser->setHtml(QCoreApplication::translate("MainWindow", "\n"
"\n"
"PK\345\272\225\350\211\262\350\257\264\346\230\216\357\274\232
\n"
"\347\272\242\350\211\262\357\274\232\350\241\200\346\210\230\344\270\255
\n"
"\347\273\277\350\211\262\357\274\232\350\256\276\350\256\241\345\231\250\350\203\234
\n"
"
"t-block-indent:0; text-indent:0px;\">\350\223\235\350\211\262\357\274\232\346\211\213\347\240\201\350\203\234
", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
看破
namespace Ui { class MainWindow; }
,并定义了私有成员变量Ui::MainWindow *ui;
源文件中包含了#include "ui_mainwindow.h"
,这个头文件哪里来的?QMetaObject::connectSlotsByName(MainWindow);
,根据名称连接槽,官方介绍如下:例子也看完了,是时候总结一下了:
上面总结的,是作者个人以为的,难免有的观点会片面,因为作者确实对Designer不是特别熟。
为什么有人会觉得只会“拖控件”的开发是比较Low的?如果你只会拖控件,可能你没有参与过稍大点的项目,可能你不经常设计自己的类,可能你编码能力偏弱,可能你只是初学者,可能你很菜……
个人觉得,要尽快摆脱“拖控件”的束缚,你看那qt-creator的代码,你看那QtitanRibbon的代码,你看那qtcanpool的代码,基本上没有ui文件,所以,你懂得……