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.exec())

这段代码是根据官网示例写的,但是原来的窗口类不是继承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.exec()

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

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.exec())

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

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    window.CenterOnScreen()
    sys.exit(app.exec())

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

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

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

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

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

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

注释掉main_layout.setSizeConstraint(QLayout.SetFixedSize)这一句之后,问题解决。

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

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

import sys from PyQt5.QtWidgets import QDesktopWidget,QMainWindow,QApplication class CenterForm(QMainWindow): def __init__(self): super(CenterForm,self).__init__()
# PySide 2(Qt for Python) 窗口 嵌入桌面示例 1. 使用win32api.Enum Windows ()枚举 窗口 ; 2. 先找到"SHELLDLL_DefView" 窗口 的父 窗口 ; 3. 再找到该 窗口 的下一层 窗口 “WorkerW”; 4. 将我们的 窗口 设为该“WorkerW” 窗口 的子 窗口 即可。 例程使用方法:右键托盘栏图标,可以选择将 窗口 嵌入桌面或将 窗口 变回正常桌面。