QStackedWidget 中的小部件共享布局

Shared layout by widgets in QStackedWidget

我有一个带有 QWidgets 的 QStackedWidget。我的 QWidgets 有点不同,一个有一个额外的按钮,另一个没有组合框等等,但它们都可以安排在同一个 QGridLayout 中。

这正是我想要实现的。我想在我的 QStackedWidget 中有一个 QGridLayout,它由我的所有 QWidget 共享。此外,我的主要 window (QDockWidget) 可以调整大小,我想为网格布局设置不同的列和行拉伸。

是否有一个干净的解决方案?

我想到了两个点子。

一种是在每个 QWidget 中都有一个 QGridLayout 并将它们连接在一起,这样当一个调整大小时,其他的也会做同样的事情。然而,我拥有的QWidgets越多,它就会越复杂。

我的第二个想法是在每个单元格中有一个带有 QStackedWidget 的 QGridLayout。 QGridLayout越大,越难维护。

None我的想法好像不错

我正在使用 PyQt4,但也欢迎使用 C++ 示例。

除了堆栈中的每个小部件都可以使用一个共享的 addWidgetsToGridLayout 函数之外,这似乎没有什么可保证的,这是一个不同的对象,因为它显示不同的东西。在此设置中共享小部件很糟糕,因此请确保堆栈中的每个小部件都有自己独特的小部件。

我不明白您为什么要在调整大小时调整不可见小部件的大小。当您切换到堆栈上的另一个小部件时,Qt 将确保调用正确的事件以正确调整布局大小。

无法共享布局。布局系统不是为它设计的。

您可以有一个在布局中创建小部件的设置函数,returns 布局。布局带有小部件。然后您可以将该布局应用于小部件,以这种方式建立内容。 setup 函数可以采用自定义其行为的参数。例如:

enum WidgetType {
  Normal, WithButton, WithCombo
};

QGridLayout* setup(WidgetType type) {
  auto l = new QGridLayout;
  l.addWidget(0, 0, new QLabel("Hello"));
  l.addWidget(0, 1, new QLabel("World"));
  switch (type) {
  case WithButton:
    l.addWidget(1, 0, new QPushButton("Click Me!"));
    break;
  case WithCombo:
    if (auto combo = new QComboBox) {
      ...
      l.addWidget(1, 1, combo);
    }
    break;
  case Normal:
    break;
  }
  return l;
};

void test() {
  QWidget w1, w2;
  w1.setLayout(setup(Normal));
  w2.setLayout(setup(WithButton));
}

当然,您可能希望轻松引用这些小部件。因此,最好创建一个可以采用多种形式的自定义小部件,并根据需要按值或指针保存小部件:

class Widget : public QWidget {
  QGridLayout m_layout{this};
  QLabel m_label1("Hello");
  QLabel m_label2("World");
  QPointer<QPushButton> m_button;
  QPointer<QComboBox> m_combo;
public:
  Widget(WidgetType type, QWidget *parent = nullptr) : QWidget(parent) {
    m_layout.addWidget(0, 0, &m_label1);
    m_layout.addWidget(0, 1, &m_label2);
    switch (type) {
    case WithButton:
      m_button = new QPushButton("Click Me!");
      m_layout.addWidget(1, 0, m_button.data());
      break;
    case WithCombo:
      m_combo = new QComboBox;
      ...
      m_layout.addWidget(1, 1, m_combo.data());
      break;
    case Normal:
      break;
    }
  }
};