代码之家  ›  专栏  ›  技术社区  ›  Saelyth

使主窗口位于PySide的顶部

  •  1
  • Saelyth  · 技术社区  · 7 年前

    场景:

    所以基本上我有3个不同的窗口和1个windows管理器文件。windows管理器启动其中一个窗口(主窗口),从中可以打开其他窗口。到现在为止,一直都还不错。但是,新窗口是 总是在最上面 在主窗口。
    如果我们打开所有窗口并单击 test1 test2 “总是在最上面”的焦点切换,我们在我们点击的那个焦点上,所以我们可以很容易地阅读每个焦点上的文本。

    问题是:

    这种行为不会发生在 main 窗户。不管怎样,主窗口总是在后面,如果其他窗口打开了,你就不能把 主要的 把它开到前面。

    我想把它带到前线,所以我一直在尝试不同的方法。windows管理器上的commented函数是我尝试过的一些事情的列表。

    笔记:

    我在Windows 10上使用Python 3.7、PySide2和Qt5.11。

    如果我没记错的话,这也会发生在PyQt5上。

    这只是最小的例子,在我的生产代码中,我们有40个窗口,比主菜单大600%,如果我们想从中打开一个新窗口,我们必须将当前窗口移到“查找”菜单的位置。

    我一直在读这样的限制可能来自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() 这窗户不好用吗?
    怎样才能得到同样的结果?

    0 回复  |  直到 7 年前
        1
  •  0
  •   Saelyth    7 年前

    在没有父项的情况下创建测试窗口解决了此问题。

    QtWidgets.QMainWindow.__init__(self)