PyQt5无法打开同一应用程序的多个窗口

时间:2018-10-13 20:59:30

标签: python pyqt pyqt5

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

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

我没有将任何附加代码添加到转换后的ui文件中,请注意此功能:

这是我的主菜单和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)

这是我的主菜单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_())

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

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

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

currentWindows = []

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

currentWindows.append(newPopWin)

这将是理想的,因此我可以跟踪所有当前打开的窗口,以便一旦我关闭主菜单就可以终止所有这些窗口。

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

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

PyQt5 打开多个窗口/小部件并关闭它们

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication, QAction
import random


class Widget2(QWidget):
    def __init__(self):
        super().__init__()
        w2btn = QPushButton('Another Widget ' +
                            str(random.randrange(5, 100, 5)), self)
        w2btn.clicked.connect(self.w2btnclicked)
        w2btn.resize(w2btn.sizeHint())
        w2btn.move(50, 50)
        
    def w2btnclicked(self):
        print("Widget 2 btn clicked")
class Widget1(QWidget):

    def __init__(self):
        super().__init__()
        self.start = 50
        self.end = 50
        quit = QAction("Quit", self)
        quit.triggered.connect(self.close)
                
        addbtn = QPushButton('Add Window', self)
        addbtn.clicked.connect(self.addbtnclicked)
        addbtn.resize(addbtn.sizeHint())
        addbtn.move(50, 50)

        quitbtn = QPushButton('Quit', self)
        quitbtn.clicked.connect(QApplication.instance().quit)
        quitbtn.resize(quitbtn.sizeHint())
        quitbtn.move(50, 100)        
        self.popups = []
        
    def addbtnclicked(self):        
        print("Add Button Clicked!!")
        wdgt2 = Widget2()
        wdgt2.show()
        
        if self.start > 1600:
            self.start = 50
            self.end = self.end + 250
        wdgt2.setGeometry(self.start, self.end, 200, 200)
        self.popups.append(wdgt2)
        self.start = self.start + 250
    
    def closeEvent(self, event):
        print("In Close Event")
        QApplication.closeAllWindows()

def main():
    app = QApplication(sys.argv)
    ex = Widget1()
    ex.show()
    ex.setGeometry(800, 600, 200, 200)
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()