【发布时间】:2017-02-01 20:33:29
【问题描述】:
我有兴趣更好地理解 Qt,为此我想了解 一个相对复杂的嵌套布局和多个小部件 GUI 示例是如何单独完成的以编程方式;即不使用 Qt Creator 的设计。
我已经看到几个示例代码只演示了非常简单的布局,并且几乎总是不使用头文件;事实上我见过的大多数例子,dump 主要是代码。我的理解是(如果我错了,请纠正我)良好的编程实践要求您将设计分离到一个单独的类中(例如mainwindow),而在main.cpp 中您只需调用主窗口和show。也许,最关键的是,所有小部件、布局等的定义都应该在头文件中定义,然后在 mainwindow.cpp 中调用和自定义。
可以看到以编程方式但相对简单的 GUI 设计的良好编程实践的一个很好的示例here。
如果有人可以提供在线资源,其中非简单代码示例展示了如何正确定义和自定义嵌套布局和小部件,将不胜感激。
或者,这里有一个简单的程序化 GUI 设计示例,如果可以从中获取代码(没有设计器)供我学习并从中获得理解,将会非常棒:
注意:我只关注嵌套布局、多个小部件以及在不同 Qt 源文件上应该在何处以及如何定义和调用这些部件。
可以在此处查看嵌套布局和小部件细节:
实际的 GUI 结果如下所示:
更新
正如 Mike 在 cmets 部分中建议的那样,从 uic 可以看到 Designer 所做的代码,在我的情况下,对于上面提到的示例如下
>uic mainwindow.ui 输出:
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QFrame>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QProgressBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QVBoxLayout *verticalLayout_3;
QFrame *top_frame;
QGridLayout *gridLayout;
QSpacerItem *horizontalSpacer;
QProgressBar *progressBar_2;
QProgressBar *progressBar_4;
QSpacerItem *verticalSpacer;
QSpacerItem *horizontalSpacer_2;
QPushButton *pushButton_1;
QProgressBar *progressBar_1;
QPushButton *pushButton_2;
QPushButton *pushButton_3;
QProgressBar *progressBar_3;
QPushButton *pushButton_4;
QFrame *bottom_frame;
QHBoxLayout *horizontalLayout;
QFrame *frame;
QFormLayout *formLayout;
QLabel *label_1;
QLabel *label_2;
QSpacerItem *verticalSpacer_2;
QLineEdit *lineEdit;
QLineEdit *lineEdit_2;
QFrame *frame_2;
QHBoxLayout *horizontalLayout_2;
QLabel *label_3;
QSpacerItem *horizontalSpacer_3;
QLabel *label_4;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QStringLiteral("MainWindow"));
MainWindow->resize(878, 632);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
verticalLayout_3 = new QVBoxLayout(centralWidget);
verticalLayout_3->setSpacing(6);
verticalLayout_3->setContentsMargins(11, 11, 11, 11);
verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
top_frame = new QFrame(centralWidget);
top_frame->setObjectName(QStringLiteral("top_frame"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(top_frame->sizePolicy().hasHeightForWidth());
top_frame->setSizePolicy(sizePolicy);
top_frame->setFrameShape(QFrame::StyledPanel);
top_frame->setFrameShadow(QFrame::Raised);
gridLayout = new QGridLayout(top_frame);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(11, 11, 11, 11);
gridLayout->setObjectName(QStringLiteral("gridLayout"));
horizontalSpacer = new QSpacerItem(30, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
gridLayout->addItem(horizontalSpacer, 0, 2, 1, 1);
progressBar_2 = new QProgressBar(top_frame);
progressBar_2->setObjectName(QStringLiteral("progressBar_2"));
progressBar_2->setValue(24);
gridLayout->addWidget(progressBar_2, 2, 3, 1, 1);
progressBar_4 = new QProgressBar(top_frame);
progressBar_4->setObjectName(QStringLiteral("progressBar_4"));
progressBar_4->setValue(24);
gridLayout->addWidget(progressBar_4, 2, 5, 1, 1);
verticalSpacer = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed);
gridLayout->addItem(verticalSpacer, 1, 1, 1, 1);
horizontalSpacer_2 = new QSpacerItem(10, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
gridLayout->addItem(horizontalSpacer_2, 0, 4, 1, 1);
pushButton_1 = new QPushButton(top_frame);
pushButton_1->setObjectName(QStringLiteral("pushButton_1"));
gridLayout->addWidget(pushButton_1, 0, 0, 1, 1);
progressBar_1 = new QProgressBar(top_frame);
progressBar_1->setObjectName(QStringLiteral("progressBar_1"));
progressBar_1->setValue(24);
gridLayout->addWidget(progressBar_1, 0, 3, 1, 1);
pushButton_2 = new QPushButton(top_frame);
pushButton_2->setObjectName(QStringLiteral("pushButton_2"));
gridLayout->addWidget(pushButton_2, 0, 1, 1, 1);
pushButton_3 = new QPushButton(top_frame);
pushButton_3->setObjectName(QStringLiteral("pushButton_3"));
gridLayout->addWidget(pushButton_3, 2, 0, 1, 1);
progressBar_3 = new QProgressBar(top_frame);
progressBar_3->setObjectName(QStringLiteral("progressBar_3"));
progressBar_3->setValue(24);
gridLayout->addWidget(progressBar_3, 0, 5, 1, 1);
pushButton_4 = new QPushButton(top_frame);
pushButton_4->setObjectName(QStringLiteral("pushButton_4"));
gridLayout->addWidget(pushButton_4, 2, 1, 1, 1);
verticalLayout_3->addWidget(top_frame);
bottom_frame = new QFrame(centralWidget);
bottom_frame->setObjectName(QStringLiteral("bottom_frame"));
bottom_frame->setFrameShape(QFrame::StyledPanel);
bottom_frame->setFrameShadow(QFrame::Raised);
horizontalLayout = new QHBoxLayout(bottom_frame);
horizontalLayout->setSpacing(6);
horizontalLayout->setContentsMargins(11, 11, 11, 11);
horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
frame = new QFrame(bottom_frame);
frame->setObjectName(QStringLiteral("frame"));
frame->setFrameShape(QFrame::StyledPanel);
frame->setFrameShadow(QFrame::Raised);
formLayout = new QFormLayout(frame);
formLayout->setSpacing(6);
formLayout->setContentsMargins(11, 11, 11, 11);
formLayout->setObjectName(QStringLiteral("formLayout"));
label_1 = new QLabel(frame);
label_1->setObjectName(QStringLiteral("label_1"));
formLayout->setWidget(0, QFormLayout::LabelRole, label_1);
label_2 = new QLabel(frame);
label_2->setObjectName(QStringLiteral("label_2"));
formLayout->setWidget(1, QFormLayout::LabelRole, label_2);
verticalSpacer_2 = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
formLayout->setItem(2, QFormLayout::LabelRole, verticalSpacer_2);
lineEdit = new QLineEdit(frame);
lineEdit->setObjectName(QStringLiteral("lineEdit"));
QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(lineEdit->sizePolicy().hasHeightForWidth());
lineEdit->setSizePolicy(sizePolicy1);
formLayout->setWidget(3, QFormLayout::SpanningRole, lineEdit);
lineEdit_2 = new QLineEdit(frame);
lineEdit_2->setObjectName(QStringLiteral("lineEdit_2"));
sizePolicy1.setHeightForWidth(lineEdit_2->sizePolicy().hasHeightForWidth());
lineEdit_2->setSizePolicy(sizePolicy1);
formLayout->setWidget(4, QFormLayout::LabelRole, lineEdit_2);
horizontalLayout->addWidget(frame);
frame_2 = new QFrame(bottom_frame);
frame_2->setObjectName(QStringLiteral("frame_2"));
frame_2->setFrameShape(QFrame::StyledPanel);
frame_2->setFrameShadow(QFrame::Raised);
horizontalLayout_2 = new QHBoxLayout(frame_2);
horizontalLayout_2->setSpacing(6);
horizontalLayout_2->setContentsMargins(11, 11, 11, 11);
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
label_3 = new QLabel(frame_2);
label_3->setObjectName(QStringLiteral("label_3"));
horizontalLayout_2->addWidget(label_3);
horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer_3);
label_4 = new QLabel(frame_2);
label_4->setObjectName(QStringLiteral("label_4"));
horizontalLayout_2->addWidget(label_4);
frame->raise();
frame->raise();
label_3->raise();
label_4->raise();
horizontalLayout->addWidget(frame_2);
verticalLayout_3->addWidget(bottom_frame);
MainWindow->setCentralWidget(centralWidget);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
pushButton_1->setText(QApplication::translate("MainWindow", "PushButton_1", 0));
pushButton_2->setText(QApplication::translate("MainWindow", "PushButton_2", 0));
pushButton_3->setText(QApplication::translate("MainWindow", "PushButton_3", 0));
pushButton_4->setText(QApplication::translate("MainWindow", "PushButton_4", 0));
label_1->setText(QApplication::translate("MainWindow", "TextLabel_1", 0));
label_2->setText(QApplication::translate("MainWindow", "TextLabel_2", 0));
label_3->setText(QApplication::translate("MainWindow", "TextLabel_3", 0));
label_4->setText(QApplication::translate("MainWindow", "TextLabel_4", 0));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
【问题讨论】:
-
推荐的做法是避免巨大的单一 GUI,将元素组织成更小的小部件并将它们组合起来,特别是如果它们可以重复,例如您的两列,每列 2 个按钮和 2 个进度条。此外,这个问题过于宽泛,主要基于意见。
-
@ddriver 尽管我明白你的意思并且你确实有观点,但我努力不让问题变得广泛,当然也不是基于意见。尽管如此,我正在寻找一小段代码来演示一些定义和调用,专门用于演示具有多个小部件的 Qt 嵌套布局供我学习;据我所知,网上没有合适的例子。
-
嵌套任何小部件就像嵌套普通的
QWidget。做一个TwoButtons : public QWidget类,你有一个有两个按钮的小部件,将其中的2 个放在另一个小部件中,你有一个有4 个按钮的小部件。只需遵循通用的 Qt 编程指南 - 小部件的属性、信号和插槽接口,以使它们真正模块化。 -
@如果你能提供一个完整的(无论多小)代码来支持你的描述,那对我来说学习会很棒。
-
@nk-fford ,即使在使用设计器时,也建议 ddriver 将元素组织成更小的小部件并将它们组合成构建块。您可以为单独的复杂小部件创建一个表单,并根据需要在主窗口或对话框中的设计器中重复使用该表单。
标签: qt qt-creator qwidget qlayout