Question

Because of their high customizability I've been relying on using multiple GroupBoxes while building app GUIs. But it appears QGroupBoxes make a certain impact on how fast an interface builds. Now with layout's .insertLayout() method I can build an entire graphics interface placing the widgets any where I want. The dialogs feel very lightweight and extremely fast to re-draw. Unfortunately I can't find a way to control their appearance. I would appreciate if you would give me some clue on how to control the layout visual properties. I am particularly interested in knowing:

  1. How to draw layout border, how to control a border line width,

  2. How to place a layout title (similar to what QGroupBox's .setTitle() does)

  3. How to control the layout outside and inside margins.

  4. How to make layout minimizable/size-restorable (So the user could click some minus/arrow icon to fold/unfold layout when they need or don't need certain widgets belonging to the same layout.

The example with three nested layouts is posted below. As it is seen on dialog screenshot there is no way to visually differentiate one layout from another since there are no border, no titles, no dividers and etc.

enter image description here

from PyQt4 import QtGui, QtCore

class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()

        tabWidget = QtGui.QTabWidget()
        tabGroupBox = QtGui.QGroupBox()
        tabLayout = QtGui.QVBoxLayout()

        tabLayout.setContentsMargins(0, 0, 0, 0)
        tabLayout.setSpacing(0)    

        subLayoutA=QtGui.QVBoxLayout()
        tabLayout.insertLayout(0, subLayoutA)

        tabGroupBox.setLayout(tabLayout)
        tabWidget.addTab(tabGroupBox,' Tab A ')

        listWidgetA = QtGui.QListWidget()
        for i in range(3): 
            QtGui.QListWidgetItem( 'Item '+str(i), listWidgetA )

        subLayoutA.addWidget(listWidgetA)

        subLayoutB=QtGui.QHBoxLayout()
        tabLayout.insertLayout(1, subLayoutB)

        subLayoutB.addWidget(QtGui.QLineEdit('LineEdit 1'))
        subLayoutB.addWidget(QtGui.QLineEdit('LineEdit 2'))

        subLayoutC=QtGui.QVBoxLayout()
        tabLayout.insertLayout(2, subLayoutC)

        subLayoutC.addWidget(QtGui.QPushButton('PushButton 1'))
        subLayoutC.addWidget(QtGui.QPushButton('PushButton 2'))
        self.setCentralWidget(tabWidget)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())

EDITED LATER

I inserted two lines into an example code to implement one of the suggestions made by sebastian. A Spacing-Margins method combos can be effectively used to get some additional tweaks done. Here is a screenshot (still could not get rid of the spacing around pushButtons):

enter image description here

Était-ce utile?

La solution

QLayout sublcasses don't have a visual representation, which becomes clear by the fact that QLayout classes do not inherit QWidget. They only calculate the positions of the widgets they are responsible for in the context of their "parent" widget.

So the answer to questions 1,2 and 4 is basically: You can't.

You'll always have to have a QWidget in combination with a QLayout. E.g. to group your two buttons into a frame with a box use a QFrame:

    subLayoutC=QtGui.QVBoxLayout()
    buttonFrame = QtGui.QFrame()
    buttonFrame.setFrameStyle(QtGui.QFrame.Plain |QtGui.QFrame.Box)
    buttonFrame.setLayout(subLayoutC)

    subLayoutC.addWidget(QtGui.QPushButton('PushButton 1'))
    subLayoutC.addWidget(QtGui.QPushButton('PushButton 2'))

    # now we add the QFrame widget - not subLayoutC to the tabLayout
    tabLayout.addWidget(buttonFrame) # I think your suggested edit was correct here
    self.setCentralWidget(tabWidget)

Concerning question 3, check the docs:

http://qt-project.org/doc/qt-4.8/qlayout.html#setContentsMargins

http://qt-project.org/doc/qt-4.8/qboxlayout.html#setSpacing

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top