tags:

views:

303

answers:

1

I have the following code:


#!/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_())

I can't get anything that I'm putting into the simfileInfoGrid to display! They'll display if I leave out the scroll area, but I need the scroll area as I will have a lot of fields to edit in the final version and I don't want to stretch the entire window over the screen.

As you see I've tried to add a size policy to simfileInfoPane, but it doesn't seem to affect anything. The area that's supposed to contain my pane stays empty!

+2  A: 

Add the pane to the scroll area after you've added all the grid's contents. In particular you need to call QScrollArea.setWidget after you have finished creating the widget you add.

I don't know exactly why this is the problem, but I do know that I tend to initialize widgets "bottom-up": I finish adding all the contents of a sub-layout before I ever add it to a parent layout. I believe this is Qt optimizing order of rendering but I could be wrong about that.

The code below is a patch, mostly so you can see where the one-line change is.

    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)
quark
Phew, I'd messed around with an ugly workaround (forcing sizes). Never would have figured out that the scroll area has to be added after the pane is ready.I am noticing some behaviour where the labels and text fields aren't resized as expected in the grid layout, eg. resizes as I resize the entire window. I guess this is normal when something has been put into a scroll area, but this means I'll have to work with size policies to fix that, too?
DaVince
Ah, nevermind that last bit. I'm new to Qt and found out it IS standard behaviour.
DaVince
If it helps: I figured this out by moving *all* the scroll area code to after the grid was initialized (which is more in keeping with my preference for keeping all changes to a widget as close together as possible.) From there I narrowed it down to the actual call. Qt tries to make things somewhat order-independent, but, as with most of programming, order always ends up mattering *somewhere*.
quark
Generally if a widget isn't sized properly you need to work with size policies and size hints. If a widget isn't showing up at all, sizes are not the problem, and order of creation and of display (`show()`) needs to be looked at.
quark
p.s. If you select an answer, it's courtesy to up-vote it as well. Stack Overflow treats these as different things (not sure why).
quark
Thanks. I wanted to upvote, but I need 15 reputation to do so. I'll upvote in due time!
DaVince