How would I destroy and recreate my window in PyQt5?
我正在练习多文件编程,正在实现一个简单的扫雷游戏。当用户开始一个新游戏时,我在窗口的主体中创建一个qpushbuttons网格。
问题是,每当一个玩家想要开始一个新的扫雷游戏,我不知道如何调整窗口大小和重置我的QpushButtons网格,以便可以玩一个新的扫雷游戏。我最初的方法是用核武器炸开原始窗口,然后用以下方法创建一个全新的窗口
1 2 3 4 5 | def newEasyGame(self): app = QApplication([]) window = minesweeperWindow(10, 10,"easy") window.show() app.exec() |
我收到错误qcoreapplication::exec:事件循环已在运行。
编辑:根据要求,这里有一个更完整的代码块,它更详细地描述了我要做的事情。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * class minesweeperDemoWindow(QMainWindow): def __init__(self, rows, cols, difficulty): super(minesweeperDemoWindow, self).__init__() #Central widget that is everything is contained within widget = QWidget() self.setCentralWidget(widget) #Vertical layout with a grid of buttons inside of it layout = QVBoxLayout() widget.setLayout(layout) #create a grid of QPushButtons that act as the playing field self.playingField = [[0 for x in range(rows)] for y in range(cols)] grid = QGridLayout() #for every row and column, add a button for r in range(0, rows): for c in range(0, cols): button = QPushButton() button.setFixedSize(30, 30) #keep track of each button's position with myRow and myCol button.setProperty("myRow", r) button.setProperty("myCol", c) button.clicked.connect(self.buttonClicked) self.playingField[r][c] = button grid.addWidget(self.playingField[r][c], r, c) layout.addLayout(grid) grid.setSpacing(0) #How a user is going to start a new game menu = self.menuBar().addMenu("&Start new Game") newEasy = QAction("Easy", self, shortcut=QKeySequence.New, triggered=self.newEasyGame) #when the Easy menu item is selected, destroy the window and create a new easy game def newEasyGame(self): app = QApplication([]) window = minesweeperWindow(10, 10,"easy") window.show() app.exec_() |
你不必破坏窗户。在这种情况下,一个可能的解决方案是消除包含qgridlayout的小部件。为此,必须创建一个方法,在必要时实现销毁逻辑并创建按钮。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | from PyQt5 import QtCore, QtGui, QtWidgets class MinesweeperDemoWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(MinesweeperDemoWindow, self).__init__(parent) levels = [ (4, 4,"level1"), (8, 8,"level2"), (16, 16,"level3"), (32, 32,"level4"), ] menu = self.menuBar().addMenu("&Start new Game") for r, c, name in levels: action = menu.addAction(name) action.setData((r, c)) action.triggered.connect(self.on_triggered) r, c, _ = levels[0] self.setSize(r, c) @QtCore.pyqtSlot() def on_triggered(self): action = self.sender() r, c = action.data() self.setSize(r, c) def setSize(self, rows, cols): # delete the old container widget = self.centralWidget() if widget is not None: widget.deleteLater() # create new container widget = QtWidgets.QWidget() self.setCentralWidget(widget) grid = QtWidgets.QGridLayout(widget) self.playingField = [[0 for x in range(rows)] for y in range(cols)] for r in range(rows): for c in range(cols): button = QtWidgets.QPushButton() button.setFixedSize(30, 30) # keep track of each button's position with myRow and myCol button.setProperty("myRow", r) button.setProperty("myCol", c) # button.clicked.connect(self.buttonClicked) self.playingField[r][c] = button grid.addWidget(button, r, c) self.setFixedSize(widget.sizeHint()) @QtCore.pyqtSlot() def buttonClicked(self): pass if __name__ =="__main__": import sys app = QtWidgets.QApplication(sys.argv) w = MinesweeperDemoWindow() w.setSize(4, 4) w.show() sys.exit(app.exec_()) |