버튼 위젯은 하나씩 활용해도 좋지만 여러개 묶어서 사용한다면 유용할 것이다. 라디오 버튼도 묶어서 사용하는 것인데 그것과 비교가 되니까 이 버튼은 QPushButton 이라 해놨다. 말 그대로 누르는 Push 버튼이다. 라디오 버튼과 뭐가 다르냐면 일단 모양이 다르고 Push 버튼의 경우 눌렀을 때 즉각적인 반응을 해야한다. 즉 이벤트 처리를 해줘야 한다.

 

 

버튼 그룹의 생성은 아래와 같다.

self.btnGroup = QButtonGroup()

클래스 사용법을 배우다 보면 느끼는데 클래스를 하나의 제품이라고 생각하는 것도 하나의 방법이다.

 

생각해보면 쿠팡에서 파는 물건들, 제품들과 다를바가 없다. 내가 만든게 아니니까 제품의 목적과 만든 사람의 의도에 맞춰서 사용해야 한다.

 

제품이 워낙 많다 보니 이 모든 제품에 대해서 알 수가 없다. 그러기에는 시간이 부족하다. 한 20년쯤 전에 프로그래머는 거의 모든 것을 암기해서 프로그래밍을 했을지 모른다. 자료가 필요하면 인터넷을 검색하는게 아니라 자료실에서 찾았다. 20년전에 구글과 스택오버플로우는 없었으니까...

 

따라서 모든 클래스에 대하여 모든 메소드와 속성을 조사하는 것은 어렵다. 물론 하나라도 더 알겠다는 열정은 있어야 한다. 그러나 그보다 중요한 것은 어떻게 빨리 효율적으로 만들 것인가이다. 효율적으로 만들어서 고객에게 서비스하는 것에 목적을 맞춰야지 클래스 하나를 더 프로그램에 넣는 것은 도움이 안된다. 영업적으로.

 

그래서 이런 클래스의 예제는 요즘 흔히 하는 유튜브의 제품 리뷰와 비슷하다. 이것을 이렇게 써보는 것 까지도 좋지만 더 좋은 것은 이것을 써봤더니 어떻더라고 알려주는 리뷰가 좋다. 지금 시점에 필요한 것인가? 아닌가? 라는 리뷰가 좋은 것 같다. 사람들의 시간과 에너지 낭비를 줄여준다. (물론 시간은 비용이니까 돈도...)

 

그런 포인트를 잡는 것도 좋은 것 같다. 이 클래스가 필요하냐 이 프레임워크가 필요하냐 라는 질문이 좀 더 본질에 가깝다. 언어의 선택에 대해서는... 웬만큼 방향이 나와있다고 본다. 언어는 그냥 산업계의 표준으로 따라가는 것 이다. 그 시점의 IT업계와 각자 처한 상황에 따라 어떤 언어를 선택할지 결정이 된다. 반면 프레임워크는 좀 더 신중할 필요가 있다. 세분화가 되기 때문이다. 그래서 프레임워크에 대해서는 앞으로는 좀더 비평적인 기록을 하려고 한다. 지금은 필자도 많은 프레임워크를 아는게 아니지만 계속 글을 쓰며 전문가들의 기고를 청취하다 보면 나아지리라 믿는다.


버튼 그룹은 버튼을 묶어주는 역할을 하기 때문에 버튼 그룹의 인스턴스에 addButton 을 해줘야한다.

 

다음 예제를 본다.

 

from PyQt5.QtWidgets import *
import sys

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(300, 300, 200, 200)

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.btnGroup = QButtonGroup()
        self.btnGroup.setExclusive(False)
        self.btnGroup.buttonClicked[int].connect(self.button_clicked)

        button = QPushButton("버튼 1")
        self.btnGroup.addButton(button, 1)
        layout.addWidget(button)

        button = QPushButton("버튼 2")
        self.btnGroup.addButton(button, 2)
        layout.addWidget(button)

    def button_clicked(self, id):
        for btn in self.btnGroup.buttons():
            if btn is self.btnGroup.button(id):
                print("[%s] 클릭!"%(btn.text()))


app = QApplication(sys.argv)
screen = Window()
screen.show()

sys.exit(app.exec_())

버튼 그룹의 인스턴스에 addButton을 한 다음에 이벤트 핸들러를 연결시켰다. 버튼이 여러개니까 [] 리스트로 연결된 것을 볼 수 있다.

 

button_clicked  핸들러는 아이디를 가지고 어떤 버튼인지 확인한다. for 문을 돌면서 찾아낸 버튼과 일치하는 경우 출력한다.

 

 

가위바위보 게임

 

그룹버튼을 활용하여 가위바위보 게임을 만들어 본다.

 

가위 바위 보 에 해당하는 푸쉬버튼을 세개 만들고 이를 그룹버튼으로 묶는다. 아이디를 1, 2, 3 으로 주고 선택한 버튼을 찾아내서 승패에 관한 정보를 콘솔과 GUI 창에 표시한다. 클래스 안에서 일어나는 일이니까 self.label을 만들어서 결과를 표시한다. label의 setText()가 요긴하게 사용된다.

 

가위바위보의 논리는 if elif else로 따지는데 반복적인 코드긴 하지만 이해하기가 쉽다. 좀 더 복잡한 동작을 만들고 싶다면 별도의 메소드를 만들어 각각 조건에 구현해주면 된다. 예를 들어 텍스트뿐 아니라 가위바위보 이미지나 애니메이션을 출력하려는 경우가 그렇다.

 

from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
from PyQt5 import QtGui
import sys
import random

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(300, 300, 500, 300)

        frame = QVBoxLayout()
        self.setLayout(frame)

        label = QLabel("[가위바위보 게임]\n준비가 되면 클릭하세요!")
        label.setAlignment(Qt.AlignCenter)
        label.setFont(QtGui.QFont('Noto Sans KR', 30))
        frame.addWidget(label)

        self.label = QLabel("")
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setFont(QtGui.QFont('Noto Sans KR', 30))
        frame.addWidget(self.label)

        layout = QHBoxLayout()
        frame.addLayout(layout)

        self.btnGroup = QButtonGroup()
        self.btnGroup.setExclusive(False)
        self.btnGroup.buttonClicked[int].connect(self.button_clicked)

        button = QPushButton("가위")
        button.setFont(QtGui.QFont('Noto Sans KR', 20))
        self.btnGroup.addButton(button, 1)
        layout.addWidget(button)

        button = QPushButton("바위")
        button.setFont(QtGui.QFont('Noto Sans KR', 20))
        self.btnGroup.addButton(button, 2)
        layout.addWidget(button)

        button = QPushButton("보")
        button.setFont(QtGui.QFont('Noto Sans KR', 20))
        self.btnGroup.addButton(button, 3)
        layout.addWidget(button)

    def button_clicked(self, id):
        for btn in self.btnGroup.buttons():
            if btn is self.btnGroup.button(id):
                player = btn.text()
                self.RockPaperScissors(player)

    def RockPaperScissors(self, player):
        cpu_choice = random.choice(['가위','바위','보'])
        print("CPU는     [" + cpu_choice +"] 를 선택했다 -", end='')

        if player == "가위":
            print("\n플레이어는 [가위]를 선택했다 -")
            if cpu_choice == "가위":
                print("*비겼다.")
                self.label.setText("무승부 게임 -")
            elif cpu_choice == "바위":
                print("*졌다~~")
                self.label.setText("졌다~ ㅠㅠ;;;")
            else:
                print("*이겼다!!!")
                self.label.setText("당신의 승리!!")

        elif player == "바위":
            print("\n플레이어는 [바위]를 선택했다 -")
            if cpu_choice == "가위":
                print("*이겼다!!!")
                self.label.setText("당신의 승리!!")
            elif cpu_choice == "바위":
                print("*비겼다.")
                self.label.setText("무승부 게임 -")
            else:
                print("*졌다~~")
                self.label.setText("졌다~ ㅠㅠ;;;")

        elif player == "보":
            print("\n플레이어는 [보]를 선택했다 -")
            if cpu_choice == "가위":
                print("*졌다~~")
                self.label.setText("졌다~ ㅠㅠ;;;")
            elif cpu_choice == "바위":
                print("*이겼다!!!")
                self.label.setText("당신의 승리!!")
            else:
                print("*비겼다.")
                self.label.setText("무승부 게임 -")




app = QApplication(sys.argv)
screen = Window()
screen.show()

sys.exit(app.exec_())

 

 

공유하기

facebook twitter kakaoTalk kakaostory naver band