PyQt 예제 2.1.1

드디어 2 버전이다...는 2 절로 넘어 온 것이다. 2절에서는 대화 상자에 대한 예제를 다루어 볼 것이다.

import sys
from functools import partial 
from PyQt4.QtCore import *
from PyQt4.QtGui import *

__version__ = "2.1.1"

class Form(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        # main dialog
        label = QLabel("Hello, PyQt")

        widgetLayout = QHBoxLayout()
        widgetLayout.addWidget(label)

        simpleButton = QPushButton("Simple Dialog")
        signalButton = QPushButton("Signal Dialog")
        connectButton = QPushButton("Connect Dialog")

        buttonLayout = QHBoxLayout()
        buttonLayout.addWidget(simpleButton)
        buttonLayout.addWidget(signalButton)
        buttonLayout.addWidget(connectButton)

        layout = QVBoxLayout()
        layout.addLayout(buttonLayout)
        layout.addLayout(widgetLayout)

        self.connect(simpleButton, SIGNAL("clicked()"), self.SimpleCall)
        self.connect(signalButton, SIGNAL("clicked()"), self.SignalCall)
        self.connect(connectButton, SIGNAL("clicked()"), self.ConnectCall)
        
        self.setLayout(layout)
        self.setWindowTitle("Main Dialog")

    def SimpleCall(self):
        SimpleDialog(self).exec_()

    def SignalCall(self):
        SignalDialog(self).exec_()

    def ConnectCall(self):
        ConnectDialog(self).exec_()


class ConnectDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        # connect part
        self.label = QLabel("Button Name")
        button1 = QPushButton("Button1")
        button2 = QPushButton("Button2")
        button3 = QPushButton("Button3")
        
        # partial connect
        self.connect(button1, SIGNAL("clicked()"),
                        partial(self.ButtonClick, "Button1"))
        self.connect(button2, SIGNAL("clicked()"),
                        partial(self.ButtonClick, "Button2"))
        self.connect(button3, SIGNAL("clicked()"),
                        partial(self.ButtonClick, "Button3"))

        button4 = QPushButton("Button4")
        button5 = QPushButton("Button5")
        button6 = QPushButton("Button6")

        # lambda connect
        self.connect(button4, SIGNAL("clicked()"),
                lambda name="Button4": self.ButtonClick(name))
        self.connect(button5, SIGNAL("clicked()"),
                lambda name="Button5": self.ButtonClick(name))
        self.connect(button6, SIGNAL("clicked()"),
                lambda name="Button6": self.ButtonClick(name))

        button7 = QPushButton("Button7")
        button8 = QPushButton("Button8")
        button9 = QPushButton("Button9")

        # sender connect
        self.connect(button7, SIGNAL("clicked()"),
                        self.SenderButtonClick)
        self.connect(button8, SIGNAL("clicked()"),
                        self.SenderButtonClick)
        self.connect(button9, SIGNAL("clicked()"),
                        self.SenderButtonClick)

        layout = QGridLayout()
        layout.addWidget(self.label, 0, 0)
        layout.addWidget(button1, 1, 0)
        layout.addWidget(button2, 2, 0)
        layout.addWidget(button3, 3, 0)
        layout.addWidget(button4, 1, 1)
        layout.addWidget(button5, 2, 1)
        layout.addWidget(button6, 3, 1)
        layout.addWidget(button7, 1, 2)
        layout.addWidget(button8, 2, 2)
        layout.addWidget(button9, 3, 2)
        layout.setRowStretch(4, 1)
        layout.setColumnStretch(3, 1)

        self.setLayout(layout)
        self.setWindowTitle("Connect Title")

    def ButtonClick(self, buttonName):
        self.label.setText(buttonName)

    def SenderButtonClick(self):
        button = self.sender()
        if not (button and isinstance(button, QPushButton)):
            return
        self.label.setText(button.text())


class SignalDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        # signal part
        spinCountLabel1 = QLabel("0")
        spinCountLabel2 = QLabel("0")
        spinCountLabel3 = QLabel("0")
        spinBox = MySignalSpinBox()

        layout = QVBoxLayout()
        layout.addWidget(spinCountLabel1)
        layout.addWidget(spinCountLabel2)
        layout.addWidget(spinCountLabel3)
        layout.addWidget(spinBox)
        layout.addStretch()

        self.connect(spinBox, SIGNAL("countup(QString)"), 
                        spinCountLabel1, SLOT("setText(QString)"))
        self.connect(spinBox, SIGNAL("countup(QString)"), 
                        spinCountLabel2.setText)
        self.connect(spinBox, SIGNAL("countup"), spinCountLabel3.setText)

        self.setLayout(layout)
        self.setWindowTitle("Signal Test")

class SimpleDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        # simple part
        self.label = QLabel("Hello, PyQt!")
        self.labelFormat = "{}"

        self.lineEidt = QLineEdit("This is LineEdit Widget")
        self.boldCheckBox = QCheckBox("굵게(&B)")
        initButton = QPushButton("초기화(&I)")
        initButton.setAutoDefault(False)
        
        buttonLayout = QHBoxLayout()
        buttonLayout.addWidget(initButton)
        buttonLayout.addStretch()

        layout = QGridLayout()
        layout.addWidget(self.label, 0, 0, 1, 2)
        layout.addWidget(self.lineEidt, 1, 0, 1, 2)
        layout.addWidget(self.boldCheckBox, 2, 0)
        layout.addLayout(buttonLayout, 3, 0)
        layout.setRowStretch(4, 1)

        self.setLayout(layout)
        self.setWindowTitle("Simple Widget")

        self.connect(self.lineEidt, SIGNAL("returnPressed()"),
                        self.UpdateLabel)
        self.connect(self.boldCheckBox, SIGNAL("stateChanged(int)"),
                        self.LabelBold)
        self.connect(initButton, SIGNAL("clicked()"), self.Initialize)
    
    def UpdateLabel(self):
        self.label.setText(self.labelFormat.format(self.lineEidt.text()))

    def LabelBold(self):
        if self.boldCheckBox.isChecked():
            self.labelFormat = "{}"
        else:
            self.labelFormat = "{}"
        self.UpdateLabel()

    def Initialize(self):
        self.labelFormat = "{}"
        self.boldCheckBox.setCheckState(Qt.Unchecked)
        self.lineEidt.setText("This is LineEdit Widget")
        self.label.setText("Hello, PyQt!")

class MySignalSpinBox(QSpinBox):
    changedCount = 0

    def __init__(self, parent=None):
        super().__init__(parent)
        self.connect(self, SIGNAL("valueChanged(int)"), self.CountChanged)

    def CountChanged(self):
        self.changedCount += 1
        self.emit(SIGNAL("countup(QString)"), str(self.changedCount))
        self.emit(SIGNAL("countup"), str(self.changedCount))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = Form()
    form.show()
    app.exec_()
diff 코드나 실제 코드나 거의 비슷한 것 같아서, 그냥 코드 전체를 올렸다.

이번 예제는 특별한 것 없이, 지난 번까지 배운 내용들에 대한 레이아웃들을 대화 상자로 변경한 것 뿐이다.

거의 코드를 옮겨 놓은 것이라고 생각하면 된다.

대화 상자를 아직 제대로 배우지는 않았지만, 계속 Form 클래스에서는 QDialog 를 상속해서 써왔다. 즉, 대화 상자를 메인 윈도우르 계속 사용해온 것이다.

그렇기 때문에 단순하게 대화 상자에서 대화 상자를 실행시키는 것은, 맨 아래에 if 문 아래의 코드처럼 사용을 하면 대화 상자가 실행된다는 것이다.

따라서 QDialog 를 상속하는 클래스 4개(Form, ConnectDialog, SignalDialog, SimpleDialog)를 만든 다음, Form 클래스에서 각각의 대화 상자를 메소드를 이용해서 호출해주면 된다.

즉, 단순하게 객체를 생성한 다음, 그 객체를 실행하면 되므로 exec_() 메소드를 바로 써주면 대화 상자가 나타난다.

그리고 객체를 생성할 때, self를 넘김으로써 대화 상자의 부모가 Form 클래스라는 것을 알려주게 된다. 따라서 자식 대화 상자가 종료되기 전까지는 부모의 윈도우는 사용할 수 없게 된다.

이를 Modal 방식이라고 하는 데, 이에 관해서는 이후에 자세히 다루겠다.

댓글 없음:

댓글 쓰기