如何在场景 QGraphicsScene 上居中小部件

Posted

技术标签:

【中文标题】如何在场景 QGraphicsScene 上居中小部件【英文标题】:How to center widgets on scene QGraphicsScene 【发布时间】:2018-12-16 23:21:25 【问题描述】:

我想在中间对齐场景。我的问题是,当您打开应用程序时,小部件以某种方式在中间下方对齐,但是在将鼠标悬停在按钮或标签上之后,小部件在中间对齐。我能以某种方式解决这个问题吗?有什么正确的方法可以让场景在视图中间对齐吗?

这是我的应用程序的全部代码:

import sys
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setFixedSize(QSize(1080, 720))
        self.setWindowTitle('Graphics Scene')
        self.centralwidget = QWidget()
        self.setCentralWidget(self.centralwidget)

        self.mainview = QGraphicsView(self.centralwidget)
        self.mainview.setGeometry(QRect(0, 0, 1080, 720))

        alignment = Qt.Alignment(Qt.AlignVCenter, Qt.AlignHCenter)
        self.mainview.setAlignment(alignment)

        # Main Scene (1)
        self.mainScene = QGraphicsScene()
        self.mainview.setScene(self.mainScene)

        self.labelTitle = QLabel('Main Scene')
        self.labelTitle.setStyleSheet('''
            QLabel 
                font: 48px 'Calibri';
                color: #999;
            
        ''')

        styleForButtons = ('''
            QPushButton 
                margin: 0 70px;
                padding: 5px 30px;
            
        ''')

        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.buttonPlay = QPushButton('Play')
        self.buttonSettings = QPushButton('Settings')
        self.buttonCredits = QPushButton('Credits')
        self.buttonMainExit = QPushButton('Exit')

        self.buttonPlay.setStyleSheet(styleForButtons)
        self.buttonSettings.setStyleSheet(styleForButtons)
        self.buttonCredits.setStyleSheet(styleForButtons)
        self.buttonMainExit.setStyleSheet(styleForButtons)

        self.buttonPlay.setSizePolicy(sizePolicy)
        self.buttonSettings.setSizePolicy(sizePolicy)
        self.buttonCredits.setSizePolicy(sizePolicy)
        self.buttonMainExit.setSizePolicy(sizePolicy)

        self.itemLabelTitle = self.mainScene.addWidget(self.labelTitle)
        self.itemButtonPlay = self.mainScene.addWidget(self.buttonPlay)
        self.itemButtonSettings = self.mainScene.addWidget(self.buttonSettings)
        self.itemButtonCredits = self.mainScene.addWidget(self.buttonCredits)
        self.itemButtonMainExit = self.mainScene.addWidget(self.buttonMainExit)

        self.mainMenuLayout = QGraphicsGridLayout()

        self.mainMenuLayout.addItem(self.itemLabelTitle, 0, 0, alignment)
        self.mainMenuLayout.addItem(self.itemButtonPlay, 1, 0)
        self.mainMenuLayout.addItem(self.itemButtonSettings, 2, 0)
        self.mainMenuLayout.addItem(self.itemButtonCredits, 3, 0)
        self.mainMenuLayout.addItem(self.itemButtonMainExit, 4, 0)

        self.mainMenuWidget = QGraphicsWidget()
        self.mainMenuWidget.setLayout(self.mainMenuLayout)
        self.mainScene.addItem(self.mainMenuWidget)

def main():
    app = QApplication(sys.argv)
    win = MyWindow()
    win.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

UPD:上传我看到的截图

我想了解为什么我的应用程序表现得如此奇怪:首先,为什么小部件没有完全居中对齐,其次,为什么会有偏移

【问题讨论】:

@eyllanesc,我想,如果您在计算机上运行此代码,应用程序的行为方式将与我相同:任何操作(悬停、击键)后小部件向上移动 你有什么版本的pyside2? @eyllanesc,1920x1080 @eyllanesc pyside2 5.11.2 @eyllanesc,PySide2.QtCore.QRectF(0.000000, 0.000000, 241.000000, 59.000000) PySide2.QtCore.QRectF(0.000000, 0.000000, 259.0000000, 201)。 【参考方案1】:

问题是因为场景没有设置sceneRect(),所以当显示QGraphicsView时,它会使用屏幕的分辨率作为基础来设置场景的大小,因此它最初可以有一个大小所有项目的boundingRect(),以便相对于该大小而不是相对于viewport()中显示的场景部分居中,就在用鼠标通过update()方法之后被调用并更新为正确的大小。所以一种解决方案是使用场景坐标中小部件的大小来设置sceneRect()

self.mainScene.setSceneRect(QRectF(QPointF(), self.mainMenuWidget.sizeHint(Qt.PreferredSize))) 
self.mainScene.addItem(self.mainMenuWidget)

【讨论】:

以上是关于如何在场景 QGraphicsScene 上居中小部件的主要内容,如果未能解决你的问题,请参考以下文章

QGraphicsItem:如何在 QGraphicsScene 调整大小时自动移动它?

如何从另一个函数更改 QGraphicsScene?

如何在 QGraphicsScene 中正确放置小部件

qt - 在 QGraphicsScene 中如何捕捉特定项目

如何阻止鼠标中键单击取消选择 QGraphicsScene 中的项目而不阻止它与场景中的项目相结合?

如何在 QGraphicsScene 上进行选择?