在 PyQt5 中打开多个窗口时遇到问题 [英] Having trouble opening multiple windows in PyQt5

查看:66
本文介绍了在 PyQt5 中打开多个窗口时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using PyQt5 designer to make a little application. I mostly work with designer rather than building from scratch so this might be a silly question. Basically i have a main menu and a "create" button that when clicked will open up the other pyqt5 .py file (also created in designer) i have been working on.

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

So far i complied the ui files into .py files and imported the popup window that i want to be able to generate more than one of and then i use this code to some success:

我没有在转换后的 ui 文件中添加任何额外的代码,除了这个功能:

I have not added any additonal code to the converted ui files excpect this function:

这是我的主菜单和弹出窗口 .py 文件中的一些代码:

Here is some code from my mainmenu and popoutwindow .py files:

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

this is the setupUi being called from my file im trying to replicate

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)

这是我的主菜单py文件:

Here is my mainmenu py file:

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_())

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

This works great for opening up ONE extra window, which stays open while my main window is open which is what i want, but then when i go to click to make another window appear, it just replaces the one i already had up, so i can only seem to have one extra at a time.

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

I figure that my old window is being referenced by self.popWin , and then being replaced over and over so my question i guess is what is the best way to go about "generating" windows instead of just referencing the same window over and over.. i tried to remove the "self" part but then the window just dosent even appear when i go to create a new window so i am kind of lost

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

for example i would expect to be able to write something like this but im not really sure how to go about doing so

currentWindows = []

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

currentWindows.append(newPopWin)

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

this would be ideal so i could keep track of all current open windows so i may terminate them all once i close my main menu.

如果能帮助我走上正轨,我将不胜感激,我曾尝试查找解决方案,但许多示例并未使用从 UI 文件转换而来的代码.

Any help would be appreciated to put me on the right track, i have tried looking up solutions but lots of examples are not using code converted from a UI file.

推荐答案

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

The problem is simple, we are overwriting an attribute and at that moment the previous element is deleted, for that reason only a window. As you point out the solution is to store it in a list.

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

But before that, I recommend you not to write your logic in the .py generated by Qt Designer since for example let's say that you want to modify something of the design, then when generating the new .py it will erase all your logic. What PyQt recommends is to use create another file where you generate the logic adviritiendote with the message: # WARNING! All changes made in this file will be lost!. So restore the previous files I called bookPopup.py and mainmenu.py by removing the openNewBook. Following the docs recommendation we obtain the following:

ma​​in.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_())

这篇关于在 PyQt5 中打开多个窗口时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆