当指定父窗口时,PyQt5窗口未在show()上打开

时间:2019-05-09 20:48:50

标签: python pyqt5

我已经定义了一个简单的主窗口和第二个弹出窗口。当我调用MainWindow.create_new_window()方法时,SecondWindow不会显示为新窗口,而是在MainWindow实例中创建其QLabel。这是代码:

import sys

from PyQt5.QtWidgets import QApplication, QPushButton, QLabel, QWidget, QVBoxLayout

class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.second_window = None

        self.main_layout = QVBoxLayout(self)

        self.new_window_button = QPushButton('New Window', self)
        self.new_window_button.clicked.connect(self.create_new_window)

        self.main_layout.addWidget(self.new_window_button)

    def create_new_window(self):
        if self.second_window is None:
            self.second_window = SecondWindow(self)
        self.second_window.show()


class SecondWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super(SecondWindow, self).__init__(*args, **kwargs)

        self.main_layout = QVBoxLayout(self)

        self.hello_label = QLabel('Hello I am the second window.', self)

        self.main_layout.addWidget(self.hello_label)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwin = MainWindow()
    mainwin.show()
    sys.exit(app.exec_())

当我创建第二个窗口而未将MainWindow实例指定为父窗口(self.second_window = SecondWindow())时,它将按预期方式打开。谁能告诉我这是怎么回事?

3 个答案:

答案 0 :(得分:1)

默认情况下,具有父级的QWidget意味着该部件将被放置在父级内部,因此您会观察到这种行为。

如果要使其成为窗口,则必须激活标志Qt::Window

# ...
from PyQt5.QtCore import Qt

# ...
class SecondWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super(SecondWindow, self).__init__(*args, **kwargs)
        self.setWindowFlags(self.windowFlags() | Qt.Window) # <---
# ...

其他选项是使用QDialog,它是一种小部件,默认情况下已经激活了该标记,并且其目的是向用户询问信息。

答案 1 :(得分:1)

摘自文档:

  

如果parent为0,则新窗口小部件将成为一个窗口。如果parent是另一个小部件,则此小部件将成为parent内部的子窗口。删除其父项后,新的窗口小部件也将被删除。

当我运行您的代码时,我将在主窗口中获取该新窗口小部件-如文档中所述。

因此,基本上,只有在有意将其用作窗口的窗口小部件(将其插入布局或用作中央窗口小部件等)时,才应将parent设置为QWidget;如果您想按原样使用它,则不需要父母。

如果您需要窗口小部件具有父项并成为单独的窗口,则更好的主意可能是使用QDialog而不是QWidget。只需将SecondWindow类的子类设为QDialog,就可以了。

示例代码(我已经将您的Windows都更改为QDialog

from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QApplication, QDialog
class MainWindow(QDialog):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.second_window = None

        self.main_layout = QVBoxLayout(self)

        self.new_window_button = QPushButton('New Window', self)
        self.new_window_button.clicked.connect(self.create_new_window)

        self.main_layout.addWidget(self.new_window_button)

    def create_new_window(self):
        if self.second_window is None:
            self.second_window = SecondWindow(self)
        # set second window as modal, because MainWindow is QDialog/QWidget.
        self.setModal(True)
        self.second_window.show()


class SecondWindow(QDialog):
    def __init__(self, *args, **kwargs):
        super(SecondWindow, self).__init__(*args, **kwargs)

        self.main_layout = QVBoxLayout(self)

        self.hello_label = QLabel('Hello I am the second window.', self)

        self.main_layout.addWidget(self.hello_label)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwin = MainWindow()
    mainwin.show()
    sys.exit(app.exec_())

答案 2 :(得分:-1)

在导入的程序包中导入该人员:

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLabel
相关问题