Я пытаюсь получить положение экрана MainWindow
после его создания. Из этого и это я узнал, что геометрия окна устанавливается после вызова show()
- но в моем случае он сохраняет значения по умолчанию, и поэтому позиция остается нулевой.
Фактическая проблема, которую я пытаюсь решить, заключается в том, чтобы QFileDialog
отображалось посередине и перед главным окном. На самом деле это должно быть поведением по умолчанию, но поскольку позиция главного окна равна нулю, диалоговое окно появляется в верхнем левом углу экрана. Пользовательский интерфейс был создан с помощью Qt-дизайнера, и я загружаю файл пользовательского интерфейса во время выполнения через файл QUiLoader
. Я заметил несколько вещей:
- Я могу сделать так, чтобы диалоговое окно появлялось посередине, если я установил положение окна с помощью
move()
илиsetGeometry()
в его реальное положение на экране послеshow()
. - Геометрия члена окна
ui
, гдеQUiLoader
загружает ui-файл, содержит правильные значения, если я взаимодействую с окном (например, внутриQPushButton
-обратного вызова), и я могу установить геометрию окна на геометриюui
в вот так:self.setGeometry(self.ui.frameGeometry())
Это то, что я делаю в данный момент, чтобы диалоговое окно появлялось посередине прямо перед отображением диалогового окна в обратном вызове определенной кнопки.
(Но все это только для контекста.)
И все же я все еще хочу знать, могу ли я заставить главное окно иметь правильное положение после show()
ing его. По этой причине я написал минимальный пример: одно окно, которое полностью закодировано на Python, одно окно, которое загружает файл пользовательского интерфейса, чтобы он выглядел так же, как первое, и некоторый код для отображения одного из окон:
import sys, os
from PySide2 import QtCore, QtWidgets, QtUiTools
class Window1(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Window1, self).__init__(parent)
self.resize(300, 200)
self.pushButton = QtWidgets.QPushButton(self, text="Print geometry")
self.pushButton.clicked.connect(self.print_geometry)
self.show() # (A)
# self.move(300, 200)
self.print_geometry() # (C)
def print_geometry(self):
self.updateGeometry() # (E)
print(self.frameGeometry())
print(self.geometry())
class Window2(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Window2, self).__init__(parent)
loader = QtUiTools.QUiLoader()
file = QtCore.QFile(os.path.abspath("TestWindow.ui"))
file.open(QtCore.QFile.ReadOnly)
self.ui = loader.load(file, parent)
file.close()
self.ui.pushButton.clicked.connect(self.print_geometry)
self.ui.show() # (A)
# self.ui.move(300, 200)
self.print_geometry() # (C)
def print_geometry(self):
self.ui.updateGeometry() # (E)
print(self.ui.frameGeometry())
print(self.ui.geometry())
app = QtWidgets.QApplication(sys.argv)
window = Window1()
# window = Window2()
# window.show() # (B)
window.print_geometry() # (D)
sys.exit(app.exec_())
Сначала хочу отметить:
- Кажется, не имеет значения, вызываю ли я
show()
в конце__init__()
или после создания окна. (А) или (Б) - Кажется, не имеет значения, вызываю ли я
print_geometry()
внутри__init__()
или после создания окна. (С) или (Г) - Вызовы
updateGeometry()
, кажется, ничего не делают. (Э)
Вывод для обоих окон всегда:
PySide2.QtCore.QRect(0, 0, 300, 200)
PySide2.QtCore.QRect(0, 0, 300, 200)
PySide2.QtCore.QRect(0, 0, 300, 200)
PySide2.QtCore.QRect(0, 0, 300, 200)
И когда я нажимаю кнопку, вывод всегда:
PySide2.QtCore.QRect(800, 418, 302, 227)
PySide2.QtCore.QRect(801, 444, 300, 200)
Мой вопрос: почему геометрия окна имеет значения по умолчанию даже после show()
, и что происходит между show()
и обратным вызовом кнопки, так что геометрия вдруг содержит правильные значения? Могу ли я эмулировать это внутри окна __init__()
после show()
? Это поведение характерно для оконного менеджера Linux Mint Cinnamon, который я использую?
TestWindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>200</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Print geometry</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>