QStackedWidget中的小部件共享布局

时间:2016-12-07 09:11:13

标签: qt qt4 pyqt4

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

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

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

我提出了两个想法。

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

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

我的想法似乎都不好。

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

2 个答案:

答案 0 :(得分:1)

除了可能用于堆栈中每个窗口小部件的共享addWidgetsToGridLayout函数之外,这似乎没有任何其他功能,因为它显示了不同的东西,因此它是一个不同的对象。在此设置中共享小部件很糟糕,因此请确保堆栈中的每个小部件都有自己独特的小部件。

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

答案 1 :(得分:0)

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

您可以拥有一个在布局中创建小部件的设置功能,并返回布局。布局包含小部件。然后,您可以将该布局应用于窗口小部件,以此方式建立内容。 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;
    }
  }
};