在 PyQt5 中打开多个窗口时遇到问题

Liv*_*ips 1 python pyqt pyqt5

我正在使用 PyQt5 设计器制作一个小应用程序。我主要与设计师合作,而不是从头开始构建,所以这可能是一个愚蠢的问题。基本上我有一个主菜单和一个“创建”按钮,单击该按钮将打开我一直在处理的其他 pyqt5 .py 文件(也在设计器中创建)。

到目前为止,我将 ui 文件编译到 .py 文件中,并导入了我希望能够生成多个弹出窗口的弹出窗口,然后我使用此代码取得了一些成功:

除了此功能之外,我没有向转换后的 ui 文件添加任何附加代码:

以下是我的 mainmenu 和 popoutwindow .py 文件中的一些代码:

这是从我尝试复制的文件中调用的 setupUi

class BookPopout(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(772, 685)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.lastNameLabel = QtWidgets.QLabel(self.centralwidget)
        self.lastNameLabel.setGeometry(QtCore.QRect(20, 110, 60, 17))
        self.lastNameLabel.setObjectName("lastNameLabel")
        self.cityEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.cityEntry.setGeometry(QtCore.QRect(20, 310, 391, 27))
        self.cityEntry.setReadOnly(True)
        self.cityEntry.setObjectName("cityEntry")
        self.bookTable = QtWidgets.QTableWidget(self.centralwidget)
        self.bookTable.setGeometry(QtCore.QRect(470, 10, 281, 481))
        font = QtGui.QFont()
        font.setPointSize(7)
        self.bookTable.setFont(font)
        self.bookTable.setAutoFillBackground(False)
        self.bookTable.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.bookTable.setRowCount(1)
        self.bookTable.setColumnCount(1)
        self.bookTable.setObjectName("bookTable")
        item = QtWidgets.QTableWidgetItem()
        self.bookTable.setItem(0, 0, item)
        self.bookTable.horizontalHeader().setVisible(False)
        self.bookTable.horizontalHeader().setCascadingSectionResizes(False)
        self.bookTable.horizontalHeader().setDefaultSectionSize(100)
        self.bookTable.horizontalHeader().setStretchLastSection(True)
        self.addressLineOneEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.addressLineOneEntry.setGeometry(QtCore.QRect(20, 190, 391, 27))
        self.addressLineOneEntry.setReadOnly(True)
        self.addressLineOneEntry.setObjectName("addressLineOneEntry")
        self.stateEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.stateEntry.setGeometry(QtCore.QRect(20, 380, 391, 27))
        self.stateEntry.setReadOnly(True)
        self.stateEntry.setObjectName("stateEntry")
        self.firstNameEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.firstNameEntry.setGeometry(QtCore.QRect(20, 70, 391, 27))
        self.firstNameEntry.setReadOnly(True)
        self.firstNameEntry.setObjectName("firstNameEntry")
        self.streetAddressLabel = QtWidgets.QLabel(self.centralwidget)
        self.streetAddressLabel.setGeometry(QtCore.QRect(20, 170, 83, 17))
        self.streetAddressLabel.setObjectName("streetAddressLabel")
        self.streetAddressTwoLabel = QtWidgets.QLabel(self.centralwidget)
        self.streetAddressTwoLabel.setGeometry(QtCore.QRect(20, 240, 220, 17))
        self.streetAddressTwoLabel.setObjectName("streetAddressTwoLabel")
        self.phoneNumberLabel = QtWidgets.QLabel(self.centralwidget)
        self.phoneNumberLabel.setGeometry(QtCore.QRect(20, 480, 87, 17))
        self.phoneNumberLabel.setObjectName("phoneNumberLabel")
        self.addressLineTwoEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.addressLineTwoEntry.setGeometry(QtCore.QRect(20, 260, 391, 27))
        self.addressLineTwoEntry.setReadOnly(True)
        self.addressLineTwoEntry.setObjectName("addressLineTwoEntry")
        self.phoneNumberEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.phoneNumberEntry.setGeometry(QtCore.QRect(20, 500, 391, 27))
        self.phoneNumberEntry.setReadOnly(True)
        self.phoneNumberEntry.setObjectName("phoneNumberEntry")
        self.firstNameLabel = QtWidgets.QLabel(self.centralwidget)
        self.firstNameLabel.setGeometry(QtCore.QRect(20, 40, 62, 17))
        self.firstNameLabel.setObjectName("firstNameLabel")
        self.cityLabel = QtWidgets.QLabel(self.centralwidget)
        self.cityLabel.setGeometry(QtCore.QRect(20, 290, 23, 17))
        self.cityLabel.setObjectName("cityLabel")
        self.stateLabel = QtWidgets.QLabel(self.centralwidget)
        self.stateLabel.setGeometry(QtCore.QRect(20, 350, 29, 17))
        self.stateLabel.setObjectName("stateLabel")
        self.zipEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.zipEntry.setGeometry(QtCore.QRect(20, 440, 391, 27))
        self.zipEntry.setReadOnly(True)
        self.zipEntry.setObjectName("zipEntry")
        self.zipLabel = QtWidgets.QLabel(self.centralwidget)
        self.zipLabel.setGeometry(QtCore.QRect(20, 410, 18, 17))
        self.zipLabel.setObjectName("zipLabel")
        self.emailEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.emailEntry.setGeometry(QtCore.QRect(20, 550, 391, 27))
        self.emailEntry.setObjectName("emailEntry")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(20, 530, 80, 17))
        self.label.setObjectName("label")
        self.confirmNewPersonButton = QtWidgets.QPushButton(self.centralwidget)
        self.confirmNewPersonButton.setGeometry(QtCore.QRect(20, 590, 85, 27))
        self.confirmNewPersonButton.setObjectName("confirmNewPersonButton")
        self.lastNameEntry = QtWidgets.QLineEdit(self.centralwidget)
        self.lastNameEntry.setEnabled(True)
        self.lastNameEntry.setGeometry(QtCore.QRect(20, 130, 391, 27))
        self.lastNameEntry.setText("")
        self.lastNameEntry.setReadOnly(True)
        self.lastNameEntry.setObjectName("lastNameEntry")
        self.sortComboBox = QtWidgets.QComboBox(self.centralwidget)
        self.sortComboBox.setGeometry(QtCore.QRect(500, 530, 101, 31))
        self.sortComboBox.setObjectName("sortComboBox")
        self.sortByLabel = QtWidgets.QLabel(self.centralwidget)
        self.sortByLabel.setGeometry(QtCore.QRect(570, 500, 71, 31))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.sortByLabel.setFont(font)
        self.sortByLabel.setObjectName("sortByLabel")
        self.sortButton = QtWidgets.QPushButton(self.centralwidget)
        self.sortButton.setGeometry(QtCore.QRect(600, 530, 111, 31))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.sortButton.setFont(font)
        self.sortButton.setObjectName("sortButton")
        self.addNewPersonButton = QtWidgets.QPushButton(self.centralwidget)
        self.addNewPersonButton.setGeometry(QtCore.QRect(40, 10, 101, 27))
        self.addNewPersonButton.setObjectName("addNewPersonButton")
        self.editEntryButton = QtWidgets.QPushButton(self.centralwidget)
        self.editEntryButton.setGeometry(QtCore.QRect(170, 10, 111, 27))
        self.editEntryButton.setObjectName("editEntryButton")
        self.confirmEditButton = QtWidgets.QPushButton(self.centralwidget)
        self.confirmEditButton.setGeometry(QtCore.QRect(20, 590, 111, 27))
        self.confirmEditButton.setObjectName("confirmEditButton")
        self.deleteEntryButton = QtWidgets.QPushButton(self.centralwidget)
        self.deleteEntryButton.setGeometry(QtCore.QRect(300, 10, 111, 27))
        self.deleteEntryButton.setObjectName("deleteEntryButton")
        self.sortByLabel_2 = QtWidgets.QLabel(self.centralwidget)
        self.sortByLabel_2.setGeometry(QtCore.QRect(530, 570, 131, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.sortByLabel_2.setFont(font)
        self.sortByLabel_2.setObjectName("sortByLabel_2")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(500, 600, 101, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.sortButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.sortButton_2.setGeometry(QtCore.QRect(600, 600, 111, 31))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.sortButton_2.setFont(font)
        self.sortButton_2.setObjectName("sortButton_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setEnabled(True)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 772, 27))
        self.menubar.setObjectName("menubar")
        self.menuOpen = QtWidgets.QMenu(self.menubar)
        self.menuOpen.setObjectName("menuOpen")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionSave = QtWidgets.QAction(MainWindow)
        self.actionSave.setObjectName("actionSave")
        self.actionSave_as = QtWidgets.QAction(MainWindow)
        self.actionSave_as.setObjectName("actionSave_as")
        self.actionClose = QtWidgets.QAction(MainWindow)
        self.actionClose.setObjectName("actionClose")
        self.menuOpen.addAction(self.actionSave)
        self.menuOpen.addSeparator()
        self.menuOpen.addAction(self.actionSave_as)
        self.menuOpen.addSeparator()
        self.menuOpen.addAction(self.actionClose)
        self.menubar.addAction(self.menuOpen.menuAction())
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
Run Code Online (Sandbox Code Playgroud)

这是我的主菜单 py 文件:

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(255, 410)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.createNewBookButton = QtWidgets.QPushButton(self.centralwidget)
        self.createNewBookButton.setGeometry(QtCore.QRect(40, 220, 171, 41))
        self.createNewBookButton.setObjectName("createNewBookButton")
        self.createNewBookButton.clicked.connect(self.openNewBook)

        self.openExistingBookButton = QtWidgets.QPushButton(self.centralwidget)
        self.openExistingBookButton.setGeometry(QtCore.QRect(40, 280, 171, 41))
        self.openExistingBookButton.setObjectName("openExistingBookButton")
        self.quitProgramButton = QtWidgets.QPushButton(self.centralwidget)
        self.quitProgramButton.setGeometry(QtCore.QRect(40, 340, 171, 41))
        self.quitProgramButton.setObjectName("quitProgramButton")
        self.mainImage = QtWidgets.QGraphicsView(self.centralwidget)
        self.mainImage.setGeometry(QtCore.QRect(10, 10, 231, 192))
        self.mainImage.setObjectName("mainImage")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def openNewBook(self):
        self.popWin = QtWidgets.QMainWindow()
        self.bookUI = bookPopout.BookPopout()
        self.bookUI.setupUi(self.popWin)
        self.popWin.show()  

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)

这非常适合打开一个额外的窗口,当我的主窗口打开时,该窗口保持打开状态,这正是我想要的,但是当我点击以显示另一个窗口时,它只是替换了我已经打开的窗口,所以我似乎一次只能多出一件。

我认为我的旧窗口被 self.popWin 引用,然后被一遍又一遍地替换,所以我想我的问题是“生成”窗口的最佳方法是什么,而不是一遍又一遍地引用同一窗口。 .我试图删除“自我”部分,但当我去创建一个新窗口时,窗口甚至没有出现,所以我有点迷失了

例如,我希望能够写出这样的东西,但我不太确定如何去做

currentWindows = []

newPopWin = QtWidgets.QMainWindow()
newBookUI = BookPopout()
newBookUI.setupUi(newPopWin)
newPopWin.show()

currentWindows.append(newPopWin)
Run Code Online (Sandbox Code Playgroud)

这将是理想的,这样我就可以跟踪所有当前打开的窗口,这样我就可以在关闭主菜单后终止它们。

任何帮助我都将不胜感激,让我走上正确的轨道,我已经尝试查找解决方案,但很多示例都没有使用从 UI 文件转换而来的代码。

eyl*_*esc 5

问题很简单,我们正在覆盖一个属性,此时前一个元素被删除,因此只有一个窗口。正如您所指出的,解决方案是将其存储在列表中。

但在此之前,我建议您不要在 Qt Designer 生成的 .py 中编写逻辑,因为例如,假设您想要修改设计的某些内容,那么在生成新的 .py 时,它将删除您的所有逻辑。PyQt 建议使用创建另一个文件,在其中生成带有消息的逻辑 adviritiendote:# WARNING! All changes made in this file will be lost!。因此,通过删除 openNewBook 来恢复我之前称为 bookPopup.py 和 mainmenu.py 的文件。根据文档建议,我们获得以下信息:

主要.py

from PyQt5 import QtCore, QtGui, QtWidgets

import bookPopout
import mainmenu


class BookPopoutWindow(QtWidgets.QMainWindow, bookPopout.BookPopout):
    def __init__(self, parent=None):
        super(BookPopoutWindow, self).__init__(parent)
        self.setupUi(self)


class MainMenu(QtWidgets.QMainWindow, mainmenu.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainMenu, self).__init__(parent)
        self.setupUi(self)
        self.createNewBookButton.clicked.connect(self.openNewBook)
        self.popups = []

    @QtCore.pyqtSlot()
    def openNewBook(self):
        popWin = BookPopoutWindow()
        popWin.show()
        self.popups.append(popWin)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainMenu()
    w.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)