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?


  • Lifetime Qt Champion

    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.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.