将 main window 置于 PySide 顶部
Bring main window to top on PySide
场景:
所以基本上我有 3 个不同的 windows 和 1 个 windows 管理器文件。 windows 管理器启动 windows(主要)之一,您可以从那里打开另一个 windows。到目前为止,一切都很好。但是,新 windows 始终位于主要 window 的顶部 。
我们可以检查一下,如果我们打开所有 windows,然后单击 test1
或 test2
,"always on top" 焦点切换,我们就会在我们单击的那个上面,所以我们可以轻松阅读每一个的文字。
问题:
main
window 不会发生此行为。无论如何,主要的 window 总是在后面,如果其他 windows 打开了,你不能把 main
window 放在前面。
我想把它放在前面,所以我一直在尝试不同的方法。 windows 管理器上的注释功能是我尝试过的一些事情的列表。
备注:
我在 Windows 10 上使用 Python 3.7、PySide2 和 Qt5.11。
如果我没记错的话,这也发生在 PyQt5 上。
这只是最小的示例,在我的生产代码中我们有 40 个 windows 比主菜单大 600%,如果我们想从中打开一个新的 window必须将我们当前的 window 移到菜单所在的 "find"。
我一直在阅读这种限制可能来自 windows 本身,但是,如果此时无事可做,我需要建议。
- 如何创建一个基于多 windows 的应用程序,而我打开的 windows 不会隐藏主菜单?
我是一名自学成才的程序员,这是我第一次为 GUI 编写 windows 管理器,所以请随时提出构建 windows 的不同方法经理。
#####################
# main_ui.py file
#####################
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(997, 554)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 997, 21))
self.menubar.setObjectName("menubar")
self.menuWindows = QtWidgets.QMenu(self.menubar)
self.menuWindows.setObjectName("menuWindows")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(10)
font.setWeight(50)
font.setBold(False)
self.statusbar.setFont(font)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionTest2 = QtWidgets.QAction(MainWindow)
self.actionTest2.setObjectName("actionTest2")
self.actionTest1 = QtWidgets.QAction(MainWindow)
self.actionTest1.setObjectName("actionTest1")
self.menuWindows.addAction(self.actionTest1)
self.menuWindows.addSeparator()
self.menuWindows.addAction(self.actionTest2)
self.menubar.addAction(self.menuWindows.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "Multiwindows tests", None, -1))
self.menuWindows.setTitle(QtWidgets.QApplication.translate("MainWindow", "Windows", None, -1))
self.actionTest2.setText(QtWidgets.QApplication.translate("MainWindow", "Test2", None, -1))
self.actionTest1.setText(QtWidgets.QApplication.translate("MainWindow", "Test1", None, -1))
#####################
# main_logic.py file
#####################
from PySide2 import QtWidgets
from PySide2.QtCore import QPoint, QSize, QEvent, Qt
from main_ui import Ui_MainWindow
class MenuForm(QtWidgets.QMainWindow, Ui_MainWindow):
"""Main window of the program."""
def __init__(self, windows_manager, parent=None):
"""Set the initial state of the window"""
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
# Initial window size/pos.
self.setMaximumSize(QSize(400, 300))
self.resize(self.maximumSize())
self.move(QPoint(300, 300))
# Pointer to windows manager
self.WINDOWS_HANDLER = windows_manager
# Buttons: QMenubar/Windows
self.actionTest1.triggered.connect(self.WINDOWS_HANDLER.open_window_test1)
self.actionTest2.triggered.connect(self.WINDOWS_HANDLER.open_window_test2)
def closeEvent(self, event):
"""Say to the windows handler that we closed this window"""
self.WINDOWS_HANDLER.window_is_closed(self)
event.accept()
# Special: Force a close of the whole program if other windows are opened
self.WINDOWS_HANDLER.kill_program()
#####################
# test1_ui.py file
#####################
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Test1(object):
def setupUi(self, Test1):
Test1.setObjectName("Test1")
Test1.setWindowModality(QtCore.Qt.NonModal)
Test1.resize(450, 259)
self.centralwidget = QtWidgets.QWidget(Test1)
self.centralwidget.setObjectName("centralwidget")
self.labelNota = QtWidgets.QLabel(self.centralwidget)
self.labelNota.setGeometry(QtCore.QRect(30, 50, 231, 111))
self.labelNota.setStyleSheet("color: rgb(100, 100, 100);")
self.labelNota.setWordWrap(True)
self.labelNota.setObjectName("labelNota")
Test1.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(Test1)
self.statusbar.setStyleSheet("")
self.statusbar.setObjectName("statusbar")
Test1.setStatusBar(self.statusbar)
self.retranslateUi(Test1)
QtCore.QMetaObject.connectSlotsByName(Test1)
def retranslateUi(self, Test1):
Test1.setWindowTitle(QtWidgets.QApplication.translate("Test1", "Test1 window", None, -1))
self.labelNota.setText(QtWidgets.QApplication.translate("Test1", "<html><head/><body><p><span style=\" font-weight:600;\">This is the test1 window.</span></p></body></html>", None, -1))
#####################
# test1_logic.py file
#####################
from PySide2 import QtWidgets
from PySide2.QtCore import QPoint, QSize
from test1_ui import Ui_Test1
class Test1Form(QtWidgets.QMainWindow, Ui_Test1):
"""Main window of the program."""
def __init__(self, windows_manager, parent=None):
"""Set the initial state of the window"""
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
# Initial window size/pos
self.setMaximumSize(QSize(300, 300))
self.resize(self.maximumSize())
self.move(QPoint(400, 100))
# Pointer to windows manager
self.WINDOWS_HANDLER = windows_manager
def closeEvent(self, event):
"""Say to the windows handler that we closed this window"""
self.WINDOWS_HANDLER.window_is_closed(self)
event.accept()
#####################
# test2_ui.py file
#####################
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Test2(object):
def setupUi(self, Test2):
Test2.setObjectName("Test2")
Test2.resize(1312, 1005)
self.centralwidget = QtWidgets.QWidget(Test2)
self.centralwidget.setObjectName("centralwidget")
self.labelNota = QtWidgets.QLabel(self.centralwidget)
self.labelNota.setGeometry(QtCore.QRect(30, 60, 201, 101))
self.labelNota.setStyleSheet("color: rgb(100, 100, 100);")
self.labelNota.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.labelNota.setWordWrap(True)
self.labelNota.setObjectName("labelNota")
Test2.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(Test2)
self.statusbar.setStyleSheet("")
self.statusbar.setObjectName("statusbar")
Test2.setStatusBar(self.statusbar)
self.retranslateUi(Test2)
QtCore.QMetaObject.connectSlotsByName(Test2)
def retranslateUi(self, Test2):
Test2.setWindowTitle(QtWidgets.QApplication.translate("Test2", "Test2 window", None, -1))
self.labelNota.setText(QtWidgets.QApplication.translate("Test2", "<html><head/><body><p>This is the test2 window</p></body></html>", None, -1))
#####################
# test1_logic.py file
#####################
from PySide2 import QtWidgets
from PySide2.QtCore import QPoint, QSize
from test2_ui import Ui_Test2
class Test2Form(QtWidgets.QMainWindow, Ui_Test2):
"""Main window of the program."""
def __init__(self, windows_manager, parent=None):
"""Set the initial state of the window"""
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
# Initial window size/pos
self.setMaximumSize(QSize(300, 300))
self.resize(self.maximumSize())
self.move(QPoint(450, 100))
# Pointer to windows manager
self.WINDOWS_HANDLER = windows_manager
def closeEvent(self, event):
"""Say to the windows handler that we closed this window"""
self.WINDOWS_HANDLER.window_is_closed(self)
event.accept()
##########################
# windows_manager.py file
##########################
from main_logic import MenuForm
from test1_logic import Test1Form
from test2_logic import Test2Form
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import Qt
class WindowsHandler(object):
"""Main handler of the windows system"""
def __init__(self):
"""Set the initial instances of the windows"""
self.active_windows = []
# Set first window - Menu one
self.menu_instance = MenuForm(self)
self.active_windows.append(self.menu_instance)
self.menu_instance.show()
def window_is_closed(self, window):
"""Choose what to do when a window is closed"""
if window in self.active_windows:
self.active_windows.remove(window)
def handle_windows(self, window_base, app=None):
"""Check if we should add or remove an item, also log it"""
for window in self.active_windows:
if isinstance(window, window_base):
self.menu_instance.statusbar.setStyleSheet("background-color: rgb(200, 0, 0);color: rgb(255, 255, 255);")
self.menu_instance.statusbar.showMessage("That window is already opened")
break
else:
if app is None:
window_instance = window_base(self, self.menu_instance)
else:
window_instance = window_base(self, self.menu_instance, app)
self.active_windows.append(window_instance)
self.menu_instance.statusbar.setStyleSheet("background-color: rgb(0, 200, 0);color: rgb(255, 255, 255);")
self.menu_instance.statusbar.showMessage("A new window has been opened")
return window_instance
return None
# def set_window_top(self, top_window):
# """Set the window as top window"""
# print("first attempt")
# top_window.setWindowState(Qt.WindowMinimized | Qt.WindowActive)
# top_window.raise_()
# top_window.activateWindow()
# top_window.showNormal()
# print("second attempt")
# top_window.setWindowFlags(Qt.WindowStaysOnTopHint)
# APPLICATION.setActiveWindow(top_window)
# top_window.raise_()
def open_window_test1(self):
"""Open the assigned window and add a pointer"""
instance = self.handle_windows(Test1Form)
if instance is not None:
instance.show()
def open_window_test2(self):
"""Open the assigned window and add a pointer"""
instance = self.handle_windows(Test2Form)
if instance is not None:
instance.show()
@staticmethod
def kill_program():
"""Close all windows to trigger an exit of the program"""
APPLICATION.closeAllWindows()
if __name__ == '__main__':
import sys
# App
APPLICATION = QApplication(sys.argv)
APPLICATION.setAttribute(Qt.AA_DisableWindowContextHelpButton)
# Project data
WINDOWS_HANDLER = WindowsHandler()
sys.exit(APPLICATION.exec_())
问题:
为什么 _raise()
不适用于此 window?
得到相同的结果有什么用?
创建没有 parent 的测试 window 解决了这个问题。
QtWidgets.QMainWindow.__init__(self)
场景:
所以基本上我有 3 个不同的 windows 和 1 个 windows 管理器文件。 windows 管理器启动 windows(主要)之一,您可以从那里打开另一个 windows。到目前为止,一切都很好。但是,新 windows 始终位于主要 window 的顶部 。
我们可以检查一下,如果我们打开所有 windows,然后单击 test1
或 test2
,"always on top" 焦点切换,我们就会在我们单击的那个上面,所以我们可以轻松阅读每一个的文字。
问题:
main
window 不会发生此行为。无论如何,主要的 window 总是在后面,如果其他 windows 打开了,你不能把 main
window 放在前面。
我想把它放在前面,所以我一直在尝试不同的方法。 windows 管理器上的注释功能是我尝试过的一些事情的列表。
备注:
我在 Windows 10 上使用 Python 3.7、PySide2 和 Qt5.11。
如果我没记错的话,这也发生在 PyQt5 上。
这只是最小的示例,在我的生产代码中我们有 40 个 windows 比主菜单大 600%,如果我们想从中打开一个新的 window必须将我们当前的 window 移到菜单所在的 "find"。
我一直在阅读这种限制可能来自 windows 本身,但是,如果此时无事可做,我需要建议。
- 如何创建一个基于多 windows 的应用程序,而我打开的 windows 不会隐藏主菜单?
我是一名自学成才的程序员,这是我第一次为 GUI 编写 windows 管理器,所以请随时提出构建 windows 的不同方法经理。
#####################
# main_ui.py file
#####################
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(997, 554)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 997, 21))
self.menubar.setObjectName("menubar")
self.menuWindows = QtWidgets.QMenu(self.menubar)
self.menuWindows.setObjectName("menuWindows")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(10)
font.setWeight(50)
font.setBold(False)
self.statusbar.setFont(font)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actionTest2 = QtWidgets.QAction(MainWindow)
self.actionTest2.setObjectName("actionTest2")
self.actionTest1 = QtWidgets.QAction(MainWindow)
self.actionTest1.setObjectName("actionTest1")
self.menuWindows.addAction(self.actionTest1)
self.menuWindows.addSeparator()
self.menuWindows.addAction(self.actionTest2)
self.menubar.addAction(self.menuWindows.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "Multiwindows tests", None, -1))
self.menuWindows.setTitle(QtWidgets.QApplication.translate("MainWindow", "Windows", None, -1))
self.actionTest2.setText(QtWidgets.QApplication.translate("MainWindow", "Test2", None, -1))
self.actionTest1.setText(QtWidgets.QApplication.translate("MainWindow", "Test1", None, -1))
#####################
# main_logic.py file
#####################
from PySide2 import QtWidgets
from PySide2.QtCore import QPoint, QSize, QEvent, Qt
from main_ui import Ui_MainWindow
class MenuForm(QtWidgets.QMainWindow, Ui_MainWindow):
"""Main window of the program."""
def __init__(self, windows_manager, parent=None):
"""Set the initial state of the window"""
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
# Initial window size/pos.
self.setMaximumSize(QSize(400, 300))
self.resize(self.maximumSize())
self.move(QPoint(300, 300))
# Pointer to windows manager
self.WINDOWS_HANDLER = windows_manager
# Buttons: QMenubar/Windows
self.actionTest1.triggered.connect(self.WINDOWS_HANDLER.open_window_test1)
self.actionTest2.triggered.connect(self.WINDOWS_HANDLER.open_window_test2)
def closeEvent(self, event):
"""Say to the windows handler that we closed this window"""
self.WINDOWS_HANDLER.window_is_closed(self)
event.accept()
# Special: Force a close of the whole program if other windows are opened
self.WINDOWS_HANDLER.kill_program()
#####################
# test1_ui.py file
#####################
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Test1(object):
def setupUi(self, Test1):
Test1.setObjectName("Test1")
Test1.setWindowModality(QtCore.Qt.NonModal)
Test1.resize(450, 259)
self.centralwidget = QtWidgets.QWidget(Test1)
self.centralwidget.setObjectName("centralwidget")
self.labelNota = QtWidgets.QLabel(self.centralwidget)
self.labelNota.setGeometry(QtCore.QRect(30, 50, 231, 111))
self.labelNota.setStyleSheet("color: rgb(100, 100, 100);")
self.labelNota.setWordWrap(True)
self.labelNota.setObjectName("labelNota")
Test1.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(Test1)
self.statusbar.setStyleSheet("")
self.statusbar.setObjectName("statusbar")
Test1.setStatusBar(self.statusbar)
self.retranslateUi(Test1)
QtCore.QMetaObject.connectSlotsByName(Test1)
def retranslateUi(self, Test1):
Test1.setWindowTitle(QtWidgets.QApplication.translate("Test1", "Test1 window", None, -1))
self.labelNota.setText(QtWidgets.QApplication.translate("Test1", "<html><head/><body><p><span style=\" font-weight:600;\">This is the test1 window.</span></p></body></html>", None, -1))
#####################
# test1_logic.py file
#####################
from PySide2 import QtWidgets
from PySide2.QtCore import QPoint, QSize
from test1_ui import Ui_Test1
class Test1Form(QtWidgets.QMainWindow, Ui_Test1):
"""Main window of the program."""
def __init__(self, windows_manager, parent=None):
"""Set the initial state of the window"""
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
# Initial window size/pos
self.setMaximumSize(QSize(300, 300))
self.resize(self.maximumSize())
self.move(QPoint(400, 100))
# Pointer to windows manager
self.WINDOWS_HANDLER = windows_manager
def closeEvent(self, event):
"""Say to the windows handler that we closed this window"""
self.WINDOWS_HANDLER.window_is_closed(self)
event.accept()
#####################
# test2_ui.py file
#####################
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Test2(object):
def setupUi(self, Test2):
Test2.setObjectName("Test2")
Test2.resize(1312, 1005)
self.centralwidget = QtWidgets.QWidget(Test2)
self.centralwidget.setObjectName("centralwidget")
self.labelNota = QtWidgets.QLabel(self.centralwidget)
self.labelNota.setGeometry(QtCore.QRect(30, 60, 201, 101))
self.labelNota.setStyleSheet("color: rgb(100, 100, 100);")
self.labelNota.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.labelNota.setWordWrap(True)
self.labelNota.setObjectName("labelNota")
Test2.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(Test2)
self.statusbar.setStyleSheet("")
self.statusbar.setObjectName("statusbar")
Test2.setStatusBar(self.statusbar)
self.retranslateUi(Test2)
QtCore.QMetaObject.connectSlotsByName(Test2)
def retranslateUi(self, Test2):
Test2.setWindowTitle(QtWidgets.QApplication.translate("Test2", "Test2 window", None, -1))
self.labelNota.setText(QtWidgets.QApplication.translate("Test2", "<html><head/><body><p>This is the test2 window</p></body></html>", None, -1))
#####################
# test1_logic.py file
#####################
from PySide2 import QtWidgets
from PySide2.QtCore import QPoint, QSize
from test2_ui import Ui_Test2
class Test2Form(QtWidgets.QMainWindow, Ui_Test2):
"""Main window of the program."""
def __init__(self, windows_manager, parent=None):
"""Set the initial state of the window"""
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
# Initial window size/pos
self.setMaximumSize(QSize(300, 300))
self.resize(self.maximumSize())
self.move(QPoint(450, 100))
# Pointer to windows manager
self.WINDOWS_HANDLER = windows_manager
def closeEvent(self, event):
"""Say to the windows handler that we closed this window"""
self.WINDOWS_HANDLER.window_is_closed(self)
event.accept()
##########################
# windows_manager.py file
##########################
from main_logic import MenuForm
from test1_logic import Test1Form
from test2_logic import Test2Form
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import Qt
class WindowsHandler(object):
"""Main handler of the windows system"""
def __init__(self):
"""Set the initial instances of the windows"""
self.active_windows = []
# Set first window - Menu one
self.menu_instance = MenuForm(self)
self.active_windows.append(self.menu_instance)
self.menu_instance.show()
def window_is_closed(self, window):
"""Choose what to do when a window is closed"""
if window in self.active_windows:
self.active_windows.remove(window)
def handle_windows(self, window_base, app=None):
"""Check if we should add or remove an item, also log it"""
for window in self.active_windows:
if isinstance(window, window_base):
self.menu_instance.statusbar.setStyleSheet("background-color: rgb(200, 0, 0);color: rgb(255, 255, 255);")
self.menu_instance.statusbar.showMessage("That window is already opened")
break
else:
if app is None:
window_instance = window_base(self, self.menu_instance)
else:
window_instance = window_base(self, self.menu_instance, app)
self.active_windows.append(window_instance)
self.menu_instance.statusbar.setStyleSheet("background-color: rgb(0, 200, 0);color: rgb(255, 255, 255);")
self.menu_instance.statusbar.showMessage("A new window has been opened")
return window_instance
return None
# def set_window_top(self, top_window):
# """Set the window as top window"""
# print("first attempt")
# top_window.setWindowState(Qt.WindowMinimized | Qt.WindowActive)
# top_window.raise_()
# top_window.activateWindow()
# top_window.showNormal()
# print("second attempt")
# top_window.setWindowFlags(Qt.WindowStaysOnTopHint)
# APPLICATION.setActiveWindow(top_window)
# top_window.raise_()
def open_window_test1(self):
"""Open the assigned window and add a pointer"""
instance = self.handle_windows(Test1Form)
if instance is not None:
instance.show()
def open_window_test2(self):
"""Open the assigned window and add a pointer"""
instance = self.handle_windows(Test2Form)
if instance is not None:
instance.show()
@staticmethod
def kill_program():
"""Close all windows to trigger an exit of the program"""
APPLICATION.closeAllWindows()
if __name__ == '__main__':
import sys
# App
APPLICATION = QApplication(sys.argv)
APPLICATION.setAttribute(Qt.AA_DisableWindowContextHelpButton)
# Project data
WINDOWS_HANDLER = WindowsHandler()
sys.exit(APPLICATION.exec_())
问题:
为什么 _raise()
不适用于此 window?
得到相同的结果有什么用?
创建没有 parent 的测试 window 解决了这个问题。
QtWidgets.QMainWindow.__init__(self)