Python + Qt, проблема QScrollArea: что не так с этим кодом?

У меня есть следующий код:


#!/usr/bin/env python

import sys
from PyQt4 import QtGui, QtCore

class SimfilePanel(QtGui.QWidget):
  '''This class provides the simfile panel shown on the right side of the main window.'''
  def __init__(self, parent=None):
    '''Load song info here.'''
    QtGui.QWidget.__init__(self, parent)

    ## Make widgets.
    # Pane with simfile information.
    simfileInfoPane = QtGui.QWidget()
    simfileInfoPane.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
    simfileInfoGrid = QtGui.QGridLayout()
    simfileInfoPane.setLayout(simfileInfoGrid)

    simfileInfoScrollArea = QtGui.QScrollArea()
    simfileInfoScrollArea.setWidget(simfileInfoPane)
    #if DEBUG: simfileInfoScrollArea.setBackgroundRole(QtGui.QPalette.Dark);

    # This will change
    labels = []
    textfields = []
    for i in range(0,20):
      labels.append( QtGui.QLabel("Label "+str(i)) )
      textfields.append( QtGui.QLineEdit() )
      labels[i].setBuddy(textfields[i])
      simfileInfoGrid.addWidget(labels[i], i, 0)
      simfileInfoGrid.addWidget(textfields[i], i, 1)

    ## Put widgets in a grid layout.
    mainvbox = QtGui.QVBoxLayout()
    mainvbox.addWidget(simfileInfoScrollArea)
    self.setLayout(mainvbox)


# Standalone testing
if __name__ == "__main__":
  app = QtGui.QApplication(sys.argv)
  panel = SimfilePanel()
  panel.show()
  sys.exit(app.exec_())

Я не могу получить ничего, что я помещаю в simfileInfoGrid для отображения! Они будут отображаться, если я оставлю область прокрутки, но мне нужна область прокрутки, так как в окончательной версии мне нужно будет редактировать много полей, и я не хочу растягивать все окно на весь экран.

Как видите, я попытался добавить политику размера в simfileInfoPane, но, похоже, это ни на что не влияет. Область, которая должна содержать мою панель, остается пустой!


person DaVince    schedule 04.12.2009    source источник


Ответы (2)


Добавьте панель в область прокрутки после добавления всего содержимого сетки. В частности, вам нужно вызвать QScrollArea.setWidget после завершения создания добавляемого виджета.

Я не знаю точно, почему это проблема, но я знаю, что я склонен инициализировать виджеты «снизу вверх»: я заканчиваю добавлять все содержимое вложенного макета до того, как добавлю его в родительский макет. Я считаю, что это Qt оптимизирует порядок рендеринга, но я могу ошибаться в этом.

Приведенный ниже код является патчем, в основном для того, чтобы вы могли видеть, где однострочное изменение.

    diff -u 1848547.py  tmp2.py
--- 1848547.py  2009-12-04 11:19:09.000000000 -0800
+++ tmp2.py 2009-12-04 11:34:58.000000000 -0800
@@ -19,7 +19,6 @@
     simfileInfoPane.setLayout(simfileInfoGrid)

     simfileInfoScrollArea = QtGui.QScrollArea()
-    simfileInfoScrollArea.setWidget(simfileInfoPane)
     #if DEBUG: 
     simfileInfoScrollArea.setBackgroundRole(QtGui.QPalette.Dark)

@@ -33,6 +32,8 @@
       simfileInfoGrid.addWidget(labels[i], i, 0)
       simfileInfoGrid.addWidget(textfields[i], i, 1)

+    simfileInfoScrollArea.setWidget(simfileInfoPane)
+
     ## Put widgets in a grid layout.
     mainvbox = QtGui.QVBoxLayout()
     mainvbox.addWidget(simfileInfoScrollArea)
person quark    schedule 04.12.2009
comment
Уф, я возился с уродливым обходным путем (форсирование размеров). Никогда бы не подумал, что область прокрутки должна быть добавлена ​​после того, как панель готова. Я заметил некоторое поведение, когда метки и текстовые поля не изменяются, как ожидалось, в макете сетки, например. изменяет размеры, когда я изменяю размер всего окна. Я думаю, это нормально, когда что-то помещается в область прокрутки, но это означает, что мне также придется работать с политиками размера, чтобы исправить это? - person DaVince; 04.12.2009
comment
Ах, не говоря уже об этом последнем кусочке. Я новичок в Qt и обнаружил, что это стандартное поведение. - person DaVince; 04.12.2009
comment
Если это поможет: я понял это, переместив все код области прокрутки после инициализации сетки (что больше соответствует моему предпочтению сохранять все изменения в виджете как можно ближе друг к другу. ) Оттуда я сузил его до фактического звонка. Qt пытается сделать вещи несколько независимыми от порядка, но, как и в большинстве программ, порядок всегда оказывается важным где-то. - person quark; 04.12.2009
comment
Как правило, если виджет имеет неправильный размер, вам нужно работать с политиками размера и подсказками размера. Если виджет вообще не отображается, проблема не в размерах, и необходимо обратить внимание на порядок создания и отображения (show()). - person quark; 04.12.2009
comment
p.s. Если вы выберете ответ, любезно также проголосовать за него. Переполнение стека рассматривает их как разные вещи (не знаю, почему). - person quark; 04.12.2009
comment
Спасибо. Я хотел проголосовать, но для этого мне нужно 15 репутации. Я проголосую в свое время! - person DaVince; 05.12.2009

Недавно я боролся с тем же самым, и я считаю, что нашел решение, которое вы ищете.

Проблема, похоже, в том, что когда вы добавляете пустой виджет в область прокрутки, он имеет размеры ноль на ноль (поскольку внутри него ничего нет).

Причина, по которой он не становится больше, заключается в том, что есть флаг с именем widgetResizable, то есть False по умолчанию.

Просто вызывая setWidgetResizable(True) в области прокрутки, виджет становится больше по мере добавления новых элементов.

Надеюсь, это поможет.

person dvreed77    schedule 24.08.2012