PyQt5弹出窗口

7
我将尝试使用PyQt5构建一个应用程序,当在QListWidget中的项目被双击时,弹出第二个窗口“popup”。
以下是代码:
import sys
from PyQt5.QtWidgets import QWidget, QListWidget, QListWidgetItem, QLabel, QPushButton, QApplication


class exampleWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        listWidget = QListWidget(self)
        listWidget.itemDoubleClicked.connect(self.buildExamplePopup)

        names = ["Jack", "Chris", "Joey", "Kim", "Duncan"]

        for n in names:
            QListWidgetItem(n, listWidget)

        self.setGeometry(100, 100, 100, 100)
        self.show()

    @staticmethod
    def buildExamplePopup(item):
        name = item.text()
        exPopup = examplePopup(name)
        exPopup.setGeometry(100, 200, 100, 100)
        exPopup.show()


class examplePopup(QWidget):
    def __init__(self, name):
        super().__init__()

        self.name = name

        self.initUI()

    def initUI(self):
        lblName = QLabel(self.name, self)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = exampleWidget()
    sys.exit(app.exec_())

当列表框中的某个名称被双击时,我希望弹出第二个窗口,但是我无论如何都无法让 examplePopup 小部件显示在屏幕上。感谢您提前的帮助。

2个回答

7

弹出窗口无法显示是因为您没有保留对它的引用,所以它会在buildExamplePopup返回时被垃圾收集。

您可以通过以下方法轻松解决此问题:

    def buildExamplePopup(self, item):
        name = item.text()
        self.exPopup = examplePopup(name)
        self.exPopup.setGeometry(100, 200, 100, 100)
        self.exPopup.show()

1
@DanielePantaleone。如果一个QWidget有父级,则不能成为顶级窗口,但是QDialog可以。在OP的示例中,如果给exampleWidget设置了父级,则它将显示为列表小部件下方的子小部件(但必须调整主窗口大小才能看到它)。这也会揭示一个关于设置父级的问题,即每次调用buildExamplePopup都会创建一个的小部件(即先前的小部件不会被销毁,因为Qt仍然引用它)。因此,使用popup.setAttribute(Qt.WA_DeleteOnClose)是一个好习惯,以避免这个问题。 - ekhumoro

3

我无法确定为何使用 QWidget 时它无法工作,因为如果第二个小部件在 __main__ 中初始化,则可以正常工作。但是您可以使用 QDialog 来实现相同的结果:

import sys

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QWidget, QListWidget, QListWidgetItem, QLabel, QApplication, QDialog


class ExampleWidget(QWidget):

    def __init__(self):
        super().__init__()
        listWidget = QListWidget(self)
        listWidget.itemDoubleClicked.connect(self.buildExamplePopup)
        for n in ["Jack", "Chris", "Joey", "Kim", "Duncan"]:
            QListWidgetItem(n, listWidget)
        self.setGeometry(100, 100, 100, 100)
        self.show()

    @pyqtSlot(QListWidgetItem)
    def buildExamplePopup(self, item):
        exPopup = ExamplePopup(item.text(), self)
        exPopup.setGeometry(100, 200, 100, 100)
        exPopup.show()


class ExamplePopup(QDialog):

    def __init__(self, name, parent=None):
        super().__init__(parent)
        self.name = name
        self.label = QLabel(self.name, self)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = ExampleWidget()
    sys.exit(app.exec_())

我还稍微修改了你的代码,给itemDoubleClicked信号槽处理程序添加了@pyqtSlot装饰器(你不应该将槽声明为静态的)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接