学习PySide6时犯了一个低级错误(窗口居中问题)

今天在学习PySide6时,犯了一个低级错误,我写了一段代码


import sys

from PySide6.QtCore import Qt
from PySide6.QtWidgets import (QApplication, QCheckBox, QDialog,
                               QDialogButtonBox, QGridLayout, QHBoxLayout,
                               QLabel, QLayout, QLineEdit, QPushButton,
                               QVBoxLayout, QWidget)


class Window(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        label = QLabel("Find &what:")
        line_edit = QLineEdit()
        label.setBuddy(line_edit)

        case_check_box = QCheckBox("Match &case")
        from_start_check_box = QCheckBox("Search from &start")
        from_start_check_box.setChecked(True)

        find_button = QPushButton("&Find")
        find_button.setDefault(True)

        button_box = QDialogButtonBox(Qt.Vertical)
        button_box.addButton(find_button, QDialogButtonBox.ActionRole)

        top_left_layout = QHBoxLayout()
        top_left_layout.addWidget(label)
        top_left_layout.addWidget(line_edit)

        left_layout = QVBoxLayout()
        left_layout.addLayout(top_left_layout)
        left_layout.addWidget(case_check_box)
        left_layout.addWidget(from_start_check_box)
        left_layout.addStretch(1)

        main_layout = QGridLayout(self)
        main_layout.setSizeConstraint(QLayout.SetFixedSize)
        main_layout.addLayout(left_layout, 0, 0)
        main_layout.addWidget(button_box, 0, 1)

        self.setWindowTitle("Extension")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app*ex.e**c())

学习PySide6时犯了一个低级错误(窗口居中问题)

运行效果

这段代码是根据官网示例写的,但是原来的窗口类不是继承QWidget的,而是继承QDialog。改成了QWidget之后再运行程序,窗口没有居中在屏幕中间了。

于是我找了一下api,并没有类似wxPython里的self.CenterOnScreen()那样可以设置屏幕居中的方法或函数。我到网上搜了一下,都是类似下面的方法

import sys
from PySide6.QtCore import Slot
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QSizePolicy
from PySide6.QtGui import QScreen


@Slot()
def move():
    center = QScreen.availableGeometry(QApplication.primaryScreen()).center()
    geo = mainwindow.frameGeometry()
    geo.moveCenter(center)
    mainwindow.move(geo.topLeft())


app = QApplication(sys.argv)
mainwindow = QMainWindow()
button = QPushButton("点我居中!", mainwindow)
button.clicked.connect(move)
mainwindow.setGeometry(0, 0, 100, 100)
mainwindow.show()

app*ex.e**c_()

我参照这个方法改了一下代码,加了个设置居中的方法

def CenterOnScreen(self):
    center = QScreen.availableGeometry(QApplication.primaryScreen()).center()
    geo = self.frameGeometry()
    geo.moveCenter(center)
    self.move(geo.topLeft())
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.CenterOnScreen()
    window.show()
    sys.exit(app*ex.e**c())

实验了一下,show()之前调用是没有任何效果的,必须放在show()之后调用才会有效果。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    window.CenterOnScreen()
    sys.exit(app*ex.e**c())

这样就行了,窗口打开时的确是居中了。但是问题来了,窗口刚开始仍旧是出现在别的位置,然后一道残影飞到了屏幕中间。呃,这也不是我想要的效果啊!我只是想它默认出现在屏幕中间而已。

在网上找了半天,也没有解决问题。然而,看我以前写的PyQt5的小程序,默认都是在屏幕中间的。也没有做什么特殊处理,唯一不一样的地方就是设置了窗口大小。

于是,在原来的程序上加了一句,设置窗口大小

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.resize(400, 300)
    window.show()
    sys.exit(app*ex.e**c())

结果窗口大致是居中了,但是窗口大小并没有改变。

main_layout = QGridLayout(self)
main_layout.setSizeConstraint(QLayout.SetFixedSize)

注释掉第二行代码后,问题解决。

总结一下,对于继承QDialog的窗口默认是居中的,而继承QWidget的窗口设置大小后默认就居中了,需要注意的是这里不能设置QLayout.SetFixedSize,加了这一句,窗口是不能调整大小并居中显示的。

以前写类似代码时,都会设置窗口大小,并没有注意到这个问题。这次没有设置窗口大小,为了把窗口居中显示在屏幕中间,可把我折腾了小半天。特写此篇,希望遇到相同问题的朋友不要再走弯路了!

如果觉得我写的内容对您有帮助,记得加关注,后续更精彩!