我正在尝试使用PyQt5(记忆游戏)开发我的第一个应用程序。
我创建了两个类: MainApplication ,它继承自QMainWindow,以及 GridWidget ,它继承自QWidget。我的目的是让用户使用menuBar的fileMenu指定包含一些图像(jpg)的文件夹。
因此,在 MainApplication 中,我创建了连接到fileMenu的方法 showDialog ,并输出了一个文件名列表(所选文件夹中图像的名称),存储在列表变量中。我希望能够将其传递给 GridWidget ,以便它可以创建并填充网格。
我对OOP编程有点新意,所以也许我的脚本组织不是最好的,我愿意接受改进建议。我的想法是将 GridWidget 添加到 MainApplication 中,但我不知道如何将 showDialog 的输出传递给它。任何建议都将不胜感激。
到目前为止,这是我的代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Memory game
My first memory game in PyQt5.
author: Umberto Minora
last edited: September 2016
"""
import os, sys, glob
from PyQt5.QtWidgets import (QMainWindow, QWidget,
QGridLayout, QPushButton, QApplication,
QAction, QFileDialog)
from PyQt5.QtGui import QPixmap
class MainApplication(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.statusBar()
openFile = QAction('Open', self)
openFile.setStatusTip('Search image folder')
openFile.triggered.connect(self.showDialog)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(openFile)
self.form_widget = GridWidget(self)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('Memory Game!')
self.show()
def showDialog(self):
folder = str(QFileDialog.getExistingDirectory(self, "Select Directory",
'/home', QFileDialog.ShowDirsOnly))
images = glob.glob(os.path.join(folder, '*.jpg'))
if images:
return images * 2
class GridWidget(QWidget):
def __init__(self):
super().__init__()
grid = QGridLayout()
self.setLayout(grid)
names = self.showDialog() # DA SISTEMARE!!!!!!
positions = [(i,j) for i in range(int(len(names)/2)) for j in range(int(len(names)/2))]
for position, name in zip(positions, names):
if name == '':
continue
button = QPushButton(name)
grid.addWidget(button, *position)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainApplication()
sys.exit(app.exec_())
修改
感谢 @ekhumoro 的回答,现在代码正常运行。这是我实际运行的代码(它不是完整的游戏,只是从文件夹中初始导入图像)。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Memory game 2
My first memory game in PyQt5.
author: Umberto Minora
last edited: September 2016
"""
import os, sys, glob, math
from PyQt5.QtWidgets import (QMainWindow, QWidget,
QGridLayout, QPushButton, QApplication,
QAction, QFileDialog, QLabel)
from PyQt5.QtGui import QPixmap
class MainApplication(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.statusBar()
openFile = QAction('Open', self)
openFile.setShortcut('Ctrl+O')
openFile.setStatusTip('Search image folder')
openFile.triggered.connect(self.showDialog)
menubar = self.menuBar()
self.fileMenu = menubar.addMenu('&File')
self.fileMenu.addAction(openFile)
self.gridWidget = QWidget(self)
self.gridLayout = QGridLayout(self.gridWidget)
self.setCentralWidget(self.gridWidget)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('Memory Game!')
self.show()
def populateGrid(self, images):
names = images * 2
n_cols = math.ceil(math.sqrt(len(names)))
n_rows = math.ceil(math.sqrt(len(names)))
positions = [(i,j) for i in range(n_cols) for j in range(n_rows)]
for position, name in zip(positions, names):
if name == '':
continue
pixmap = QPixmap(name)
scaled = pixmap.scaled(pixmap.width()/3, pixmap.height()/3)
del(pixmap)
lbl = QLabel(self)
lbl.setPixmap(scaled)
self.gridLayout.addWidget(lbl, *position)
def showDialog(self):
folder = str(QFileDialog.getExistingDirectory(self, "Select Directory",
'.', QFileDialog.ShowDirsOnly))
images = glob.glob(os.path.join(folder, '*.jpg'))
if images:
self.populateGrid(images)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainApplication()
sys.exit(app.exec_())
答案 0 :(得分:1)
我认为如果将所有内容保存在一个类中会更简单。您应该使每个子窗口小部件成为该类的属性,以便稍后可以使用类的方法中的self
来访问它们。所有的程序逻辑都将放在方法中 - 所以只需要调用方法来响应信号和事件。
以下是该课程的样子:
class MainApplication(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.statusBar()
openFile = QAction('Open', self)
openFile.setStatusTip('Search image folder')
openFile.triggered.connect(self.showDialog)
menubar = self.menuBar()
self.fileMenu = menubar.addMenu('&File')
self.fileMenu.addAction(openFile)
self.gridWidget = QWidget(self)
self.gridLayout = QGridLayout(self.gridWidget)
self.setCentralWidget(self.gridWidget)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('Memory Game!')
self.show()
def populateGrid(self, images):
names = images * 2
positions = [(i,j) for i in range(int(len(names)/2)) for j in range(int(len(names)/2))]
for position, name in zip(positions, names):
if name == '':
continue
button = QPushButton(name)
self.gridLayout.addWidget(button, *position)
def showDialog(self):
folder = str(QFileDialog.getExistingDirectory(self, "Select Directory",
'/home', QFileDialog.ShowDirsOnly))
images = glob.glob(os.path.join(folder, '*.jpg'))
if images:
self.populateGrid(images)