Reputation: 3578
I am trying to create my first memory game.
I recently found out how to have it working thanks to the answer of my question here. The working code is posted in the same link, but now I am trying to keep the widgets and the main application classes separated 1) because I think it's better, and 2) because I would like to in order to learn better how OOP works.
So, I here post my new code, which seems to work except the very last part. The concept:
I am pretty sure the problem is in the very final row of populate_grid, where I add elements to the grid layout, but I can't find out how to solve the problem.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Memory game 3
My first memory game in PyQt5.
author: Umberto Minora
last edited: September 2016
"""
import os
import sys
import glob
import math
from PyQt5.QtWidgets import (QMainWindow, QWidget,
QGridLayout, QPushButton, QApplication,
QAction, QFileDialog, QLabel)
from PyQt5.QtGui import QPixmap
class MainApplication(QMainWindow):
"""This is the main application.
All widgets should be put inside it."""
def __init__(self, widget):
super().__init__()
self.widget = widget
self.initUI()
def showDialog(self):
folder = str(QFileDialog.getExistingDirectory(self, "Select Directory",
'.', QFileDialog.ShowDirsOnly))
images = glob.glob(os.path.join(folder, '*.jpg'))
if images:
self.widget.populate_grid(images)
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.setCentralWidget(self.widget)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('Memory Game!')
self.show()
class MemoryGame(QWidget):
"""This is the Memory Game Widget"""
def __init__(self):
super().__init__()
self.gridWidget = QWidget(self)
self.gridLayout = QGridLayout(self.gridWidget)
def populate_grid(self, images):
n_cols = math.ceil(math.sqrt(len(images)))
n_rows = math.ceil(math.sqrt(len(images)))
positions = [(i,j) for i in range(n_cols) for j in range(n_rows)]
for position, img in zip(positions, images):
if img == '':
continue
pixmap = QPixmap(img)
scaled = pixmap.scaled(pixmap.width()/3, pixmap.height()/3)
del(pixmap)
lbl = QLabel(self)
lbl.setPixmap(scaled)
self.gridLayout.addWidget(lbl, *position)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainApplication(MemoryGame())
sys.exit(app.exec_())
Upvotes: 1
Views: 328
Reputation: 120618
The reason why the images aren't showing is because you put the gridWidget
inside the MemoryGame
widget, which doesn't have a layout itself. The MemoryGame
widget should actually replace the gridWidget
, so all you need to do is this:
class MemoryGame(QWidget):
"""This is the Memory Game Widget"""
def __init__(self):
super().__init__()
self.gridLayout = QGridLayout(self)
I also think the way you create the MemoryGame
widget is unnecessarily convoluted. Custom widget classes should be treated like any other. There's no need to pass it into the MainApplication
constructor like that - just create it directly inside initUi
:
def initUI(self):
...
self.widget = MemoryGame()
self.setCentralWidget(self.widget)
Upvotes: 1