PySide QtGui.QGraphicsWidget child-parent transformations
-
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?
-
Hi and welcome to devnet,
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.