在Qt中手动设置窗口布局的正确方法

Posted

技术标签:

【中文标题】在Qt中手动设置窗口布局的正确方法【英文标题】:Proper way to manually set the layout of a window in Qt 【发布时间】:2015-09-20 12:08:26 【问题描述】:

我需要一个 QMainWindow 布局来根据内核数量进行更改。 因此我手动设置(不使用设计模式)。

我的问题是: 创建此布局后,如何引用它包含的小部件?

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);

    //...
    buildLayout();
    //...

    // Now I'd like to use something like this:
    // ui->threadingTable->...
    // However, it's not the member of ui


void MainWindow::buildLayout()

    QWidget *window = new QWidget(this);

    QTableView *threadingTable = new QTableView(window);
    //...

    QGridLayout *layout = new QGridLayout(window);
    layout->addWidget(threadingTable, 0, 0);
    //...

    window->setLayout(layout);
    this->setCentralWidget(window);

我可以从this->centralWidget() 中获取 QLayoutItem。 或者我可以在 MainWindow 类的布局成员中制作所有小部件并直接访问它们。

但是,我觉得这些都不是正确的方法。

有没有办法将小部件传递给 ui? 这样我就可以通过调用来访问它们 ui->threadingTable

【问题讨论】:

在我看来,使小部件也成为“主”类的成员并没有错。当然,您通常不需要访问所有这些,并且在将它们添加到布局之前可能会连接信号。 【参考方案1】:

这两个选项都很好。可以从主类成员或直接从对象层次结构中获取指向threadingTable 的指针:

qDebug() << qobject_cast<QGridLayout *>(this->centralWidget()->layout())->itemAtPosition(0, 0)->widget();
qDebug() << this->centralWidget()->layout()->itemAt(0)->widget();

当然,null 可能需要验证。也可以查看这个问题QGridLayout: Getting the list of QWidget added。

Ui::MainWindow 类是从设计模式下可以生成的.ui xml 表单自动生成的:"Using a Designer UI File in Your Application"

由于布局是手动构建的,.ui 文件和ui 实例根本不需要。您可以将它们从您的项目中移除。

另一方面,即使在 .ui 表单中的设计模式下,也可以使用自定义小部件。 因此,如果您需要一些棘手的对象,您可以在方便的设计模式下构建整个表单,然后,例如,标准的QTableView 可能会升级为继承自QTableViewCustomTableView。该自定义类可能会实现一些特殊行为。

【讨论】:

以上是关于在Qt中手动设置窗口布局的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

QT怎么设置控件在窗口大小发生变化的时候,使控件始终居于右上角

Qt 的几个核心机制总结之 布局(QWidget可以设置setSizePolicy,而QSizePolicy有Fixed,minimum,maximum,preferred,expanding,ign

如pyside2程序显示的窗口与qt designer中的设置不符怎么办?

明确设置值时抑制Qt信号的正确方法是啥

win10qt软件控件大小

QT 如何设置选择本地文件窗口