Stop widgets from overlapping each other and add space between them - python

I am using QHBoxLayout for layout. The breakdown is: pic.1 is what happens, pic.2 is what I want - widgets don't overlap and there is a gap between them. For pic.2, I created a Gap widget to stick between the existing widgets. But this is a cumbersome solution which implies extra maintenance (especially when I have more than two widgets to care for). Moreover, since B overlaps A, I think the newly added gap widget overlaps A as well, maybe according the fraction of its size. I am not so sure about this.
I tried using self.layout.addSpacing(10), but that doesn't work. The red widget shifts by 10 pixels from where it was before, not from the border of the widget on the left.
Note, too, that the contained widgets will all have some minimum width specification.
So, how can I add the space between two widgets like in pic.2?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Gap(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setMinimumWidth(10)
self.setMinimumHeight(1)
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
# Set layout
self.layout = QHBoxLayout()
self.setLayout(self.layout)
# Set palette
self.palette1 = QPalette()
self.palette1.setColor(QPalette.Window, Qt.red)
self.palette2 = QPalette()
self.palette2.setColor(QPalette.Window, Qt.blue)
self.palettebg = QPalette()
self.palettebg.setColor(QPalette.Window, Qt.green)
self.setAutoFillBackground(True)
self.setPalette(self.palettebg)
# Set labels
self.label1 = QLabel(self)
self.label1.setText("A")
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.adjustSize()
self.label1.setAutoFillBackground(True)
self.label1.setPalette(self.palette1)
self.label1.setMinimumSize(36, 36)
self.label2 = QLabel(self)
self.label2.setText("B")
self.label2.move(30, 0)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.adjustSize()
self.label2.setAutoFillBackground(True)
self.label2.setPalette(self.palette2)
self.label2.setMinimumSize(36, 36)
self.gap = Gap()
self.layout.addWidget(self.label1)
# self.layout.addWidget(self.gap)
# self.layout.addSpacing(10)
self.layout.addWidget(self.label2)
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5'
self.left = 10
self.top = 10
self.width = 200
self.height = 54
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.line = Line(self)
self.line.resize(74, 54)
self.line.move(50, 50)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
# CUSTOM
app.setFont(QFontDatabase().font("Monospace", "Regular", 14))
ex = App()
sys.exit(app.exec_())
EDIT clarification, as requested: (1) suppose the size of the parent widget is too small (and cannot be resized), (2) the parent widget has QHBoxLayout with widgets A and B added to it, (3) the parent widget being too small, QHBoxLayout aranges the child widgets A and B such that they overlap each other like in the first picture. (4) Such overlap is undesirable, instead the widgets just need to be placed one after another, with no overlap, and with gap between them, like in picture 2. I don't know how to do this with QHBoxLayout.
EDIT 2 Here is a visual explanation.
The green here is the parent widget - not resizable by assumption. Widget A is added:
Add widget B:
Now, widget B is on top of A. I don't want it. I want this instead:

The minimumSize of the child widgets does not influence the minimumSize of the parent widget, and the use of the layout does not influence the minimumSize of the widget either. The layouts set the minimumSizeHint and sizeHint using as information the minimumSize of the widgets that handle plus other features such as the size and sizing policy. So in the first instance you must set the minimumSize of the parent widget to be the minimumSizeHint of it.
On the other hand the layout has a spacing by default so it is advisable to set it to 0.
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
# Set layout
layout = QHBoxLayout(self, spacing=0)
layout.addWidget(self.label1)
layout.addSpacing(10)
layout.addWidget(self.label2)
self.setMinimumSize(self.minimumSizeHint())
# or
# layout = QHBoxLayout(self, spacing=10)
# layout.addWidget(self.label1)
# layout.addWidget(self.label2)
# self.setMinimumSize(self.minimumSizeHint())
Update:
The maximum size of the layout that can be handled is the size of the parent widget, so in its case it will compress not respecting the spaces, a solution is to set a widget that is the content, and in that to establish the layout, so the layout will stretch to the content widget with freedom.
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
content_widget = QWidget(self)
layout = QHBoxLayout(content_widget, spacing=10)
layout.addWidget(self.label1)
layout.addWidget(self.label2)
content_widget.setFixedSize(content_widget.minimumSizeHint())

Related

Add dockable widgets in quadrants using PyQt

I'm creating a GUI using PyQt, to display 4 images in a window, positioned in this way:
Top left
Top right
Bottom left
Bottom right
I'd like to be able to undock them, but also to redock them back to any of the 4 available space.
My final goal is to set it up so that moving an undocked image where another one is already placed, would move that second image out of the way (docking it in another free quadrant or undocking it), or that placing it in the center would make it occupy all the 4 quadrants (undocking all the others).
I've tried achieving this with QDockWidget, but so far I'm not achieving good results.
My current code:
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Window")
grid_layout = QGridLayout()
dock_window_1 = QMainWindow()
docked = QDockWidget("Dockable", self)
dock_window_1.addDockWidget(Qt.DockWidgetArea.TopDockWidgetArea, docked)
dockedWidget = QWidget(self)
docked.setWidget(dockedWidget)
dockedWidget.setLayout(QVBoxLayout())
dockedWidget.layout().addWidget(QPushButton("1"))
dock_window_2 = QMainWindow()
docked_2 = QDockWidget("Dockable_2", self)
dock_window_2.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, docked_2)
dockedWidget_2 = QWidget(self)
docked.setWidget(dockedWidget_2)
dockedWidget_2.setLayout(QVBoxLayout())
dockedWidget_2.layout().addWidget(QPushButton("2"))
dock_window_3 = QMainWindow()
docked_3 = QDockWidget("Dockable_3", self)
dock_window_3.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, docked_3)
dockedWidget_3 = QWidget(self)
docked.setWidget(dockedWidget_3)
dockedWidget_3.setLayout(QVBoxLayout())
dockedWidget_3.layout().addWidget(QPushButton("3"))
dock_window_4 = QMainWindow()
docked_4 = QDockWidget("Dockable_4", self)
dock_window_4.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, docked_4)
dockedWidget_4 = QWidget(self)
docked.setWidget(dockedWidget_4)
dockedWidget_4.setLayout(QVBoxLayout())
dockedWidget_4.layout().addWidget(QPushButton("4"))
grid_layout.addWidget(dock_window_1, 0, 0)
grid_layout.addWidget(dock_window_2, 1, 0)
grid_layout.addWidget(dock_window_3, 0, 1)
grid_layout.addWidget(dock_window_4, 1, 1)
widget = QWidget()
widget.setLayout(grid_layout)
self.setCentralWidget(widget)
This kind of works, but I'm only able to redock a widget in its original place.
Can anyone help me getting on the right road here?
Thanks in advance!
Most of the behavior you are describing is actually already implemented by Qt using the QMainWindow and the QDockWidget.
The issue with your code is you are creating a unique QMainWindow for each of the QDockWidgets when the program only needs one QMainWindow. Additionally you are adding each of the QDockWidgets to the layout after you have already added them using the standard dockAreas surrounding the central widget.
If you eliminate the unneeded QMainWindows and instead assign each of the QDockWidgets to the your MainWindow, your desired functionality should work automatically.
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Window")
grid_layout = QGridLayout()
docked = QDockWidget("Dockable", self)
docked.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
dockedWidget = QWidget(self)
docked.setWidget(dockedWidget)
dockedWidget.setLayout(QVBoxLayout())
dockedWidget.layout().addWidget(QPushButton("1"))
docked_2 = QDockWidget("Dockable_2", self)
docked_2.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
dockedWidget_2 = QWidget(self)
docked_2.setWidget(dockedWidget_2)
dockedWidget_2.setLayout(QVBoxLayout())
dockedWidget_2.layout().addWidget(QPushButton("2"))
docked_3 = QDockWidget("Dockable_3", self)
docked_3.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
dockedWidget_3 = QWidget(self)
docked_3.setWidget(dockedWidget_3)
dockedWidget_3.setLayout(QVBoxLayout())
dockedWidget_3.layout().addWidget(QPushButton("3"))
docked_4 = QDockWidget("Dockable_4", self)
docked_4.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
dockedWidget_4 = QWidget(self)
docked_4.setWidget(dockedWidget_4)
dockedWidget_4.setLayout(QVBoxLayout())
dockedWidget_4.layout().addWidget(QPushButton("4"))
self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, docked)
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, docked_2)
self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, docked_3)
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, docked_4)
widget = QWidget()
widget.setLayout(grid_layout)
self.setCentralWidget(widget)

How to position labels with move command based on their center instead of left corner in PyQt5

Hi I have several QLabels in a Qwidget. I am given a design that I need to create in Qt and it has only few labels actually. But one of labels' text my change. So text length is also changable. I used move() command it takes left corner point as reference point. I need to take center point of Label as reference point I guess.
class App(QWidget):
def __init__(self):
super().__init__()
self.left = 0
self.top = 0
self.width = 480
self.height = 800
self.initUI()
def initUI(self):
#self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Create widget
main_page = QLabel(self)
main_pixmap = QPixmap('main_page')
main_page.setPixmap(main_pixmap)
#logo
logo = QLabel(self)
logo_pixmap = QPixmap('logo')
logo.setPixmap(logo_pixmap)
logo.move(159,63)
#Date
today = format_date(datetime.datetime.now(),"dd MMMM", locale = 'tr').upper()
day = format_date(datetime.datetime.now(), "EEEE", locale = 'tr').upper()
date = QLabel(self)
date.setText(day + " " + today )
date.setFont(QFont("Lato", 24))
date.setStyleSheet('color:white')
self.move_to_center()
#Clock
clock = QLabel(self)
clock.setText(strftime('%H:%M'))
clock.setFont(QFont("Lato", 90))
clock.setStyleSheet('color:white')
clock.move(71,222)
How can I dynamicly put a label horizantally middle of a Qwidget?
Edit:
When I used layouts, labels lines up one after another as below
The main problem with centering widgets is that they can alter their size according to their contents.
The simpler solution for your case is to create a label that has a fixed width and has its text center aligned:
clock = QLabel(self)
clock.setText(strftime('%H:%M'))
clock.setFixedWidth(self.width())
clock.move(0, 222)
clock.setAlignment(Qt.AlignCenter)
While this is fine, there is a couple of problems:
if the label has more than one line and you don't want it to span over the whole width, the alignment will always be centered (which can be ugly);
if the original text is on one line and the new text has more, it won't be updated properly (unless you call label.adjustSize() after every text change)
Another solution is to create a subclass of QLabel that automatically repositions itself as soon as it's shown or the text is changed:
class CenterLabel(QLabel):
vPos = 0
def setText(self, text):
super(CenterLabel, self).setText(text)
if self.parent():
self.center()
def setVPos(self, y):
# set a vertical reference point
self.vPos = y
if self.parent():
self.center()
def center(self):
# since there's no layout, adjustSize() allows us to update the
# sizeHint based on the text contents; we cannot use the standard
# size() as it's unreliable when there's no layout
self.adjustSize()
x = (self.parent().width() - self.sizeHint().width()) / 2
self.move(x, self.vPos)
That said, I still think that using a layout is a better and simpler solution. You just have to create the "background" pixmap with the main widget as a parent and without adding it to the layout, then set the layout and add everything else using layout.addSpacing for the vertical spacings between all widgets.
The only issue here is that if a label text changes its line count, all subsequent widgets will be moved accordingly. If that's the case, just set a fixed height for the widget which will be equal to the distance between the top of the widget and the top of the next, then add the widget to the layout ensuring that it is horizontally centered and top aligned.
def initUI(self):
#self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self._width, self._height)
self.background = QLabel(self)
self.background.setPixmap(QPixmap('background.png'))
layout = QVBoxLayout()
self.setLayout(layout)
# set spacing between items to 0 to ensure that there are no added margins
layout.setSpacing(0)
# add a vertical spacing for the top margin;
# I'm just using random values
layout.addSpacing(20)
main_page = QLabel(self)
main_pixmap = QPixmap('main_page')
main_page.setPixmap(main_pixmap)
# add the widget ensuring that it's horizontally centered
layout.addWidget(main_page, alignment=Qt.AlignHCenter)
#logo
logo = QLabel(self)
logo_pixmap = QPixmap('logo')
logo.setPixmap(logo_pixmap)
layout.addWidget(logo, alignment=Qt.AlignHCenter)
layout.addSpacing(50)
#Date
today = format_date(datetime.datetime.now(),"dd MMMM", locale = 'tr').upper()
day = format_date(datetime.datetime.now(), "EEEE", locale = 'tr').upper()
date = QLabel(self)
date.setText(day + " " + today )
date.setFont(QFont("Lato", 24))
date.setStyleSheet('color:white')
# set a fixed height equal to the vertical position of the next label
date.setFixedHeight(100)
# ensure that the label is always on top of its layout "slot"
layout.addWidget(date, alignment=Qt.AlignHCenter|Qt.AlignTop)
#Clock
clock = QLabel(self)
clock.setText(strftime('%H:%M'))
clock.setFont(QFont("Lato", 90))
clock.setStyleSheet('color:white')
layout.addWidget(clock, alignment=Qt.AlignHCenter|Qt.AlignTop)
# add a bottom "stretch" to avoid vertical expanding of widgets
layout.addStretch(1000)

Is it possible to set a width for a Widget without Fixing it?

I'm trying to set the width of a QScrollArea in PyQt5, but the only thing I found is setting the width through the
scroll.setFixedWidth(360)
function.
The issue is when I put the scroll bar area in a QSplitter
self.splitter2 = QSplitter(Qt.Horizontal)
self.splitter2.addWidget(scroll)
I cannot resize the scroll bar area width with the mouse any more.
What I would like to do is set the width of the scrollbar area (100 for instance) and be able to modify it afterwards when I click and drag the middle line of the QSplitter. For now it is one (set the width of the scrollbar area) or the other (modify the width with the mouse) - but not both at the same time.
Here's a minimal example:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class Viewer(QMainWindow):
def __init__(self, parent=None):
super(Viewer, self).__init__()
self.parent = parent
self.centralWidget= QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX = QHBoxLayout()
self.setFixedWidth(200)
self.setFixedHeight(200)
label1 = QLabel('blablabalblablabalblablabalblablabalblablabalblablabalblablabalblablabalblablabal')
label2 = QLabel('blablabal again')
scroll = QScrollArea()
scroll.setFixedWidth(100)
scroll.setWidget(label1)
scroll.setWidgetResizable(True)
self.splitter2 = QSplitter(Qt.Horizontal)
self.splitter2.addWidget(scroll)
self.splitter2.addWidget(label2)
self.mainHBOX.addWidget(self.splitter2)
self.centralWidget.setLayout(self.mainHBOX)
def main():
app = QApplication(sys.argv)
ex = Viewer(app)
ex.setWindowTitle('window')
# ex.showMaximized()
ex.show()
sys.exit(app.exec_( ))
if __name__ == '__main__':
main()
You should set the initial position of the splitter handle rather than setting the width of its child widgets. This can be done using QSplitter.setSizes:
leftwidth = 100
self.splitter2.setSizes([leftwidth, self.width() - leftwidth])
But note that the splitter won't allow moving its handle to a position less than the minimum width of a child widget. The default minimum width for a scroll-area is 100. So in the above example, setting leftwidth = 50 wouldn't work properly unless you explicitly reset the minimum width of the scroll-area accordingly.

PySide QtGui.QGraphicsWidget child-parent transform

I have a question about using QtGui.QGraphicsWidget. In a given example I will try to describe my problem. There are two QGraphicsWidget instances inside the QtGui.QtGraphicsScene, of which one is a parent (app_widget.main_widget - blue one when running), and other one is its child widget (app_widget.subwidget - red one when running). If you run the program, with a Plus key on your keyboard you can transform widgets circularly through the states.
# --coding: utf-8 --
# window.py
import sys
from PySide import QtGui, QtCore
class WidgetBase(QtGui.QGraphicsWidget):
def __init__(self, parent = None):
super(WidgetBase, self).__init__(parent)
def set_background(self, color_hex):
palette = QtGui.QPalette()
color = QtGui.QColor()
color.setRgba(color_hex)
palette.setColor(QtGui.QPalette.Background, color)
self.setPalette(palette)
self.setAutoFillBackground(True)
class AppWidget(WidgetBase):
def __init__(self):
super(AppWidget, self).__init__()
self.main_widget = WidgetBase(self)
self.subwidget = WidgetBase(self.main_widget)
class Window(QtGui.QMainWindow):
change_app_state = QtCore.Signal()
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
SCREEN_DIM = QtGui.QDesktopWidget().screenGeometry()
self.app_scene = QtGui.QGraphicsScene(0, 0, SCREEN_DIM.width(), SCREEN_DIM.height())
app_view = QtGui.QGraphicsView(self.app_scene)
app_view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
app_view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setCentralWidget(app_view)
app_widget = AppWidget()
app_widget.main_widget.set_background(0x50449558)
app_widget.main_widget.resize(500, 500)
app_widget.subwidget.set_background(0x50ff3300)
app_widget.subwidget.resize(500 * 0.5, 500)
self.app_scene.addItem(app_widget)
self.machine = QtCore.QStateMachine()
state1 = QtCore.QState(self.machine)
state2 = QtCore.QState(self.machine)
state3 = QtCore.QState(self.machine)
state4 = QtCore.QState(self.machine)
state1.assignProperty(app_widget.main_widget, 'geometry', QtCore.QRectF(0, 0, 500, 500))
state2.assignProperty(app_widget.main_widget, 'scale', 0.5)
state3.assignProperty(app_widget.main_widget, 'scale', 1)
state4.assignProperty(app_widget.main_widget, 'geometry', QtCore.QRectF(0, 0, 1000, 500))
trans1 = state1.addTransition(self.change_app_state, state2)
trans2 = state2.addTransition(self.change_app_state, state3)
trans3 = state3.addTransition(self.change_app_state, state4)
trans4 = state4.addTransition(self.change_app_state, state1)
trans1.addAnimation(QtCore.QPropertyAnimation(app_widget.main_widget, 'scale', state1))
trans2.addAnimation(QtCore.QPropertyAnimation(app_widget.main_widget, 'scale', state2))
trans3.addAnimation(QtCore.QPropertyAnimation(app_widget.main_widget, 'geometry', state3))
trans4.addAnimation(QtCore.QPropertyAnimation(app_widget.main_widget, 'geometry', state4))
self.machine.setInitialState(state1)
self.machine.start()
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Plus:
self.change_app_state.emit()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.showFullScreen()
sys.exit(app.exec_())
When scaling parent widget (changing 'scale' property - QtGui.QGraphicsWidget property inherited from QtGui.QGraphicsObject), a child widget also get scaled. But, when I change geometry of parent widget (changing 'geometry' property - QtGui.QGraphicsWidget property), child widget geometry remains unchanged.
I am running Python 2.7.6, PySide version 1.2.1 and QtCore version 4.8.6.
Why isn't a child widget always following parents transformations? Is there any way to scale only one axis of parent widget and get all children widgets to get scaled proportionally?
Answered on qt forum.
"It will only follow it's parent widget if you put it in a layout that you set on the said parent widget. Otherwise it's up to you to handle the positioning and size of the child widget."
Link on qt forum post:
https://forum.qt.io/topic/59958/pyside-qtgui-qgraphicswidget-child-parent-transformations

Qt Widget with slider

I'm writing GUI application using PyQt4 and I need to create widgets and dialog windows which can be slided vertically. After clicking "Add new widgets" button (and moving it down) I create dynamically new small widgets (containing 2 textEdit objects). I want to avoid situation when window's height will be too small to properly show all widgets so the obvious solution seems to be a slider. I tried to use QSlider but I'm not sure if it's the best way and how to configure such slider.
class MyDialog(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.smallWidgets = list()
self.resize(450,500)
self.buttonPosition = 60
firstWidget = SmallWidget(self)
firstWidget.setGeometry(QRect(5,5, 450, 80))
self.addWidgetButton = QPushButton(self)
self.addWidgetButton.setText("Add new widget")
self.addWidgetButton.setGeometry(QRect(165,self.buttonPosition,120,40))
self.connect(self.addWidgetButton, QtCore.SIGNAL("clicked()"), self.addNewWidget)
def addNewWidget(self):
newWidget = SmallWidget(self)
newWidget.setGeometry(QRect(5,self.buttonPosition, 450, 80))
self.buttonPosition += 70
newWidget.setVisible(True)
self.smallWidgets.append(newWidget)
self.addWidgetButton.setGeometry(QRect(165,self.buttonPosition,120,40))
So I took #ekhumoro advice and implemented this using layout and QScrollArea (thanks! That's what I was looking for!). Scrolling works as I wanted, but I suppose my implementation is not the ideal solution. ;)
class MyDialog(QDialog):
def __init__(self, strt, parent=None):
QDialog.__init__(self, parent)
self.smallWidgets = list()
self.setMinimumWidth(450)
self.setMinimumHeight(600)
self.setupLayout()
self.setupScrollArea()
self.addWidgetButton = QPushButton(self.containerWidget)
self.addWidgetButton.setText("Add new widget")
self.layout.addWidget(self.addWidgetButton)
self.connect(self.addWidgetButton, QtCore.SIGNAL("clicked()"), self.addNewWidget)
def setupLayout(self):
self.containerWidget = QWidget(self)
self.widgetHeight = 120
self.containerWidget.setGeometry(QRect(0,0,450,self.widgetHeight))
self.layout = QVBoxLayout()
self.containerWidget.setLayout(self.layout)
def setupScrollArea(self):
self.scrollArea = QScrollArea(self)
self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.scrollArea.setMaximumWidth(440)
self.scrollArea.setMinimumHeight(600)
self.scrollArea.setWidgetResizable(False)
self.scrollArea.setWidget(self.containerWidget)
def addNewWidget(self):
newWidget = SmallWidget(self.containerWidget)
widgetPosition = len(self.smallWidgets)
self.layout.insertWidget(widgetPosition, newWidget)
self.smallWidgets.append(newWidget)
self.widgetHeight += 80
self.containerWidget.resize(450,self.widgetHeight)

Categories

Resources