私は最初のメモリゲームを作成しようとしています。PyQt5:QActionの後にMainApplicationのレイアウトをウィジェットメソッドで更新する
私は最近、私の質問hereの答えのおかげで働く方法を見つけました。ワーキングコードは同じリンクに掲載されていますが、私はウィジェットとメインアプリケーションクラスを1)分離しておくことをお勧めします。2)OOPの仕組みをより良く学びたいからです。
ここでは、最後の部分を除いて動作するように思われる新しいコードを掲載します。概念:
- MainApplicationは、画像のフォルダへのパスを可能にするメニューバーを有し、交互に空QGridLayoutを初期化MemoryGameウィジェットをインスタンス化します。
- メニューバーで[ファイル] - > [開く]をクリックすると、のshowDialogというメソッドが呼び出されます。
- フォルダを選択すると、populate_grid(MemoryGame objの)メソッドが呼び出されます。
- populate_grid QGridLayoutに見つかったイメージのそれぞれを "should"で埋めてください。
- グリッドが画面に表示されるはずですが、それは、私は、問題は、私はグリッドレイアウトに要素を追加populate_grid、非常に最後の行にあるかなり確信しています....
ではありませんしかし、私は問題を解決する方法を見つけることができません。あなたは、レイアウト自体を持っていないMemoryGame
ウィジェット、内部のgridWidget
を置くため
#!/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_())
おかげで再び!とにかく、MainApplicationを他のゲーム(PokerGameなど)で実装したいと考えています。メインアプリケーションを子ウィジェットと区別する方が良いのではないでしょうか?もちろん、私のMainApplicationは非常にシンプルなので、どうなるかについてもっと考えています。 – umbe1987
複数のゲームが必要な場合は、各ゲームは完全に自己完結型でなければなりません。現在のところ、あなたのメモリゲームは2つのクラスに分割されています。それぞれのクラスは、他のクラスなしでは機能しません。複数のゲームでは、各ゲームはそれ自身の特殊なメニューを提供する必要もあります。メインアプリケーションはゲームのメインウィジェットをロードし、メインメニューバーにゲームのメニューを表示する責任がありますが、ゲームは他のすべてを行います。ゲームには汎用インターフェイスが必要で、メインアプリケーションではそれらを「ブラックボックス」として扱う必要があります。 – ekhumoro