첫 번째 메모리 게임을 만들려고합니다.PyQt5 : 위젯 메서드를 통해 QAction 후 MainApplication 레이아웃 업데이트
저는 최근에 내 질문 here의 대답 덕분에 작동 방법을 알아 냈습니다. 작업 코드는 동일한 링크에 게시되었지만 이제는 위젯과 기본 응용 프로그램 클래스를 1) 분리 된 상태로 유지하려고 노력하고 있습니다. 2) OOP의 작동 방식을 더 잘 배우기 위해서입니다.
그래서 여기에 마지막 코드를 제외하고는 작동하는 새 코드가 게시됩니다. 개념 :
- MainApplication 이미지의 폴더 경로를 허용하는 도구 모음을 가지고 있으며, 회전의 빈 QGridLayout를 초기화 MemoryGame 위젯을 인스턴스화합니다.
- 메뉴 모음에서 파일 -> 열기를 클릭하면 showDialog 메서드가 호출됩니다.
- 폴더를 선택하면 populate_grid (MemoryGame obj의) 메서드가 호출됩니다.
- populate_grid "발견 된 각 이미지로 QGridLayout을 채워야"합니다.
- 그리드가 화면에 표시되지만 그렇지 않은되어야한다 ....
그 문제는 내가 그리드 레이아웃에 요소를 추가 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