(메인 윈도우 클래스에서 상속 받는 클래스가 QDialog 이다. 즉, 대화 상자였다.)
그러나 다음 절부터는 진짜 메인 윈도우를 구현하고 작동시켜 볼 것이다. 따라서 이번 예제에서는 지금까지 작성한 코드를 모듈화 시키는 것이다. main 윈도우 부분과 나머지 대화 상자 부분으로 구성을 하여서 더 이상 대화 상자 부분의 코드는 관리하지 않도록 할 것이다.
그러므로 이번 예제에서는 단순하게 코드만 보여주겠다.
먼저, mainDialog.py 이다.
#!/usr/bin/env python3 # Copyright (C) 2011년 bluekyu (http://blog.bluekyu.me/) # 이 프로그램은 자유 소프트웨어입니다. 소프트웨어의 피양도자는 자유 소프트웨어 # 재단이 공표한 GNU 일반 공중 사용 허가서 2판 또는 그 이후 판을 임의로 # 선택해서, 그 규정에 따라 프로그램을 개작하거나 재배포할 수 있습니다. # 이 프로그램은 유용하게 사용될 수 있으리라는 희망에서 배포되고 있지만, # 특정한 목적에 맞는 적합성 여부나 판매용으로 사용할 수 있으리라는 묵시적인 # 보증을 포함한 어떠한 형태의 보증도 제공하지 않습니다. 보다 자세한 사항에 # 대해서는 GNU 일반 공중 사용 허가서를 참고하시기 바랍니다. # Main 대화 상자 import sys from PyQt4.QtCore import * from PyQt4.QtGui import * import simpleSignalConnectDlg as sscDlg import introDialog as introDlg __version__ = "2.2.5" class MainDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.liveDialog = None # Buttons simpleButton = QPushButton("Simple Dialog") signalButton = QPushButton("Signal Dialog") connectButton = QPushButton("Connect Dialog") dumbButton = QPushButton("Dumb Dialog") standardButton = QPushButton("Standard Dialog") smartButton = QPushButton("Smart Dialog") liveButton = QPushButton("Live Dialog") buttonLayout = QGridLayout() buttonLayout.addWidget(simpleButton, 0, 0) buttonLayout.addWidget(signalButton, 0, 1) buttonLayout.addWidget(connectButton, 0, 2) buttonLayout.addWidget(dumbButton, 1, 0) buttonLayout.addWidget(standardButton, 1, 1) buttonLayout.addWidget(smartButton, 1, 2) buttonLayout.addWidget(liveButton, 1, 3) buttonLayout.setColumnStretch(3, 1) self.connect(simpleButton, SIGNAL("clicked()"), self.SimpleCall) self.connect(signalButton, SIGNAL("clicked()"), self.SignalCall) self.connect(connectButton, SIGNAL("clicked()"), self.ConnectCall) self.connect(dumbButton, SIGNAL("clicked()"), self.DumbCall) self.connect(standardButton, SIGNAL("clicked()"), self.StandardCall) self.connect(smartButton, SIGNAL("clicked()"), self.SmartCall) self.connect(liveButton, SIGNAL("clicked()"), self.LiveCall) # Label textNameLabel = QLabel("Text Name: ") self.textLabel = QLabel("Hello, PyQt") # ComboBox Label comboBoxNameLabel = QLabel("ComboBox Name: ") self.comboBoxLabel = QLabel("What Item") labelLayout = QFormLayout() labelLayout.addRow(textNameLabel, self.textLabel) labelLayout.addRow(comboBoxNameLabel, self.comboBoxLabel) # SpinBox spinBoxLabel = QLabel("Spin Box(&S): ") self.spinBox = QSpinBox() spinBoxLabel.setBuddy(self.spinBox) self.spinBox.setRange(0, 100) self.spinBox.setValue(0) spinBoxLayout = QHBoxLayout() spinBoxLayout.addWidget(spinBoxLabel) spinBoxLayout.addWidget(self.spinBox) # Dial dialLabel = QLabel("Dial(&D): ") self.dial = QDial() dialLabel.setBuddy(self.dial) self.dial.setRange(0, 100) self.dial.setValue(0) self.dial.setNotchesVisible(True) dialLayout = QHBoxLayout() dialLayout.addWidget(dialLabel) dialLayout.addWidget(self.dial) # Slider sliderLabel = QLabel("Slider(&L): ") self.slider = QSlider(Qt.Horizontal) sliderLabel.setBuddy(self.slider) self.slider.setRange(0, 100) self.slider.setValue(0) sliderLayout = QHBoxLayout() sliderLayout.addWidget(sliderLabel) sliderLayout.addWidget(self.slider) # Widget layout widgetLayout = QVBoxLayout() widgetLayout.addLayout(labelLayout) widgetLayout.addLayout(spinBoxLayout) widgetLayout.addLayout(dialLayout) widgetLayout.addLayout(sliderLayout) widgetLayout.addStretch() # Main Layout layout = QVBoxLayout() layout.addLayout(buttonLayout) layout.addLayout(widgetLayout) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.setWindowTitle("Main Dialog") def SimpleCall(self): sscDlg.SimpleDialog(self).exec_() def SignalCall(self): sscDlg.SignalDialog(self).exec_() def ConnectCall(self): sscDlg.ConnectDialog(self).exec_() def DumbCall(self): dialog = introDlg.DumbDialog(self) comboBoxIndex = dialog.comboBox.findText(self.comboBoxLabel.text()) if comboBoxIndex == -1: comboBoxIndex = 0 dialog.comboBox.setCurrentIndex(comboBoxIndex) dialog.textLineEdit.setText(self.textLabel.text()) dialog.slider.setValue(self.spinBox.value()) if dialog.exec_(): self.comboBoxLabel.setText(dialog.comboBox.currentText()) self.textLabel.setText(dialog.textLineEdit.text()) self.spinBox.setValue(dialog.slider.value()) def StandardCall(self): values = {"label" : self.textLabel.text(), "comboBox" : self.comboBoxLabel.text(), "dial" : self.dial.value()} dialog = introDlg.StandardDialog(values, self) if dialog.exec_(): values = dialog.getResult() self.textLabel.setText(values["label"]) self.comboBoxLabel.setText(values["comboBox"]) self.dial.setValue(values["dial"]) def SmartCall(self): def update(): self.textLabel.setText(self.values["label"]) self.comboBoxLabel.setText(self.values["comboBox"]) self.slider.setValue(self.values["slider"]) self.values = {"label" : self.textLabel.text(), "comboBox" : self.comboBoxLabel.text(), "slider" : self.slider.value()} dialog = introDlg.SmartDialog(self.values, self) self.connect(dialog, SIGNAL("changed"), update) dialog.show() def LiveCall(self): def update(): self.textLabel.setText(self.values["label"]) self.comboBoxLabel.setText(self.values["comboBox"]) self.slider.setValue(self.values["slider"]) self.values = {"label" : self.textLabel.text(), "comboBox" : self.comboBoxLabel.text(), "slider" : self.slider.value()} if self.liveDialog is None: self.liveDialog = introDlg.LiveDialog(self.values, update, self) self.liveDialog.refresh(self.values) self.liveDialog.show() self.liveDialog.raise_() self.liveDialog.activateWindow() if __name__ == "__main__": app = QApplication(sys.argv) mainDlg = MainDialog() mainDlg.show() app.exec_()
그리고 맨 처음에 작성했던 대화 상자들이다. simpleSignalConnectDlg.py 이다.
#!/usr/bin/env python3 # Copyright (C) 2011년 bluekyu (http://blog.bluekyu.me/) # 이 프로그램은 자유 소프트웨어입니다. 소프트웨어의 피양도자는 자유 소프트웨어 # 재단이 공표한 GNU 일반 공중 사용 허가서 2판 또는 그 이후 판을 임의로 # 선택해서, 그 규정에 따라 프로그램을 개작하거나 재배포할 수 있습니다. # 이 프로그램은 유용하게 사용될 수 있으리라는 희망에서 배포되고 있지만, # 특정한 목적에 맞는 적합성 여부나 판매용으로 사용할 수 있으리라는 묵시적인 # 보증을 포함한 어떠한 형태의 보증도 제공하지 않습니다. 보다 자세한 사항에 # 대해서는 GNU 일반 공중 사용 허가서를 참고하시기 바랍니다. # Simple, Signal, Connect 대화 상자들 import sys from functools import partial from PyQt4.QtCore import * from PyQt4.QtGui import * __version__ = "2.2.5" 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) layout.setSizeConstraint(QLayout.SetFixedSize) 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 nameLabel1 = QLabel("Qt SIGNAL - Qt SLOT: ") nameLabel2 = QLabel("Qt SIGNAL - Method: ") nameLabel3 = QLabel("Short Circuit SIGNAL - Method: ") spinBoxLabel = QLabel("값 변경: ") spinCountLabel1 = QLabel("0") spinCountLabel2 = QLabel("0") spinCountLabel3 = QLabel("0") spinBox = MySignalSpinBox() layout = QFormLayout() layout.addRow(nameLabel1, spinCountLabel1) layout.addRow(nameLabel2, spinCountLabel2) layout.addRow(nameLabel3, spinCountLabel3) layout.addRow(spinBoxLabel, spinBox) layout.setSizeConstraint(QLayout.SetFixedSize) 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) layout.setSizeConstraint(QLayout.SetFixedSize) 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) simpleDlg = SimpleDialog() signalDlg = SignalDialog() connectDlg = ConnectDialog() simpleDlg.show() signalDlg.show() connectDlg.show() app.exec_()
마지막으로 2절에서 작성했던 대화 상자들이다. introDialog.py 이다.
#!/usr/bin/env python3 # Copyright (C) 2011년 bluekyu (http://blog.bluekyu.me/) # 이 프로그램은 자유 소프트웨어입니다. 소프트웨어의 피양도자는 자유 소프트웨어 # 재단이 공표한 GNU 일반 공중 사용 허가서 2판 또는 그 이후 판을 임의로 # 선택해서, 그 규정에 따라 프로그램을 개작하거나 재배포할 수 있습니다. # 이 프로그램은 유용하게 사용될 수 있으리라는 희망에서 배포되고 있지만, # 특정한 목적에 맞는 적합성 여부나 판매용으로 사용할 수 있으리라는 묵시적인 # 보증을 포함한 어떠한 형태의 보증도 제공하지 않습니다. 보다 자세한 사항에 # 대해서는 GNU 일반 공중 사용 허가서를 참고하시기 바랍니다. # 대화 상자 종류들 import sys from PyQt4.QtCore import * from PyQt4.QtGui import * __version__ = "2.2.5" class LiveDialog(QDialog): def __init__(self, arg, update, parent=None): super().__init__(parent) textEditLabel = QLabel("Main 레이블 변경: ") self.textLineEdit = QLineEdit(arg["label"]) valueEditLabel = QLabel("Main 슬라이더 변경: ") self.valueLineEdit = QLineEdit(str(arg["slider"])) self.valueLineEdit.setInputMask("900") comboBoxLabel = QLabel("Combo Box(&C): ") self.comboBox = QComboBox() comboBoxLabel.setBuddy(self.comboBox) for item in ["item1", "item2", "item3", "item4", "item5"]: self.comboBox.addItem(item) comboBoxIndex = self.comboBox.findText(arg["comboBox"]) if comboBoxIndex == -1: comboBoxIndex = 0 self.comboBox.setCurrentIndex(comboBoxIndex) self.result = arg self.update = update widgetLayout = QFormLayout() widgetLayout.addRow(textEditLabel, self.textLineEdit) widgetLayout.addRow(valueEditLabel, self.valueLineEdit) widgetLayout.addRow(comboBoxLabel, self.comboBox) self.connect(self.textLineEdit, SIGNAL("textEdited(QString)"), self.apply) self.connect(self.valueLineEdit, SIGNAL("textEdited(QString)"), self.checkFix) self.connect(self.comboBox, SIGNAL("currentIndexChanged(int)"), self.apply) layout = QVBoxLayout() layout.addLayout(widgetLayout) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.setWindowTitle("Live Dialog") def checkFix(self): valueText = self.valueLineEdit.text() if len(valueText) == 0 or int(valueText) < 0 or int(valueText) > 100: self.valueLineEdit.setText("0") self.valueLineEdit.selectAll() self.valueLineEdit.setFocus() self.apply() def apply(self): value = int(self.valueLineEdit.text()) self.result["label"] = self.textLineEdit.text() self.result["comboBox"] = self.comboBox.currentText() self.result["slider"] = value self.update() def refresh(self, arg): self.textLineEdit.setText(arg["label"]) self.valueLineEdit.setText(str(arg["slider"])) comboBoxIndex = self.comboBox.findText(arg["comboBox"]) if comboBoxIndex == -1: comboBoxIndex = 0 self.comboBox.setCurrentIndex(comboBoxIndex) self.result = arg class SmartDialog(QDialog): def __init__(self, arg, parent=None): super().__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) textEditLabel = QLabel("Main 레이블 변경: ") self.textLineEdit = QLineEdit(arg["label"]) valueEditLabel = QLabel("Main 슬라이더 변경: ") self.valueLineEdit = QLineEdit(str(arg["slider"])) self.valueLineEdit.setInputMask("900") comboBoxLabel = QLabel("Combo Box(&C): ") self.comboBox = QComboBox() comboBoxLabel.setBuddy(self.comboBox) for item in ["item1", "item2", "item3", "item4", "item5"]: self.comboBox.addItem(item) comboBoxIndex = self.comboBox.findText(arg["comboBox"]) if comboBoxIndex == -1: comboBoxIndex = 0 self.comboBox.setCurrentIndex(comboBoxIndex) self.result = arg widgetLayout = QFormLayout() widgetLayout.addRow(textEditLabel, self.textLineEdit) widgetLayout.addRow(valueEditLabel, self.valueLineEdit) widgetLayout.addRow(comboBoxLabel, self.comboBox) applyButton = QPushButton("적용(&A)") cancelButton = QPushButton("취소") buttonBox = QDialogButtonBox() buttonBox.addButton(applyButton, QDialogButtonBox.ApplyRole) buttonBox.addButton(cancelButton, QDialogButtonBox.RejectRole) applyButton.setDefault(True) self.connect(applyButton, SIGNAL("clicked()"), self.apply) self.connect(buttonBox, SIGNAL("rejected()"), self, SLOT("reject()")) layout = QVBoxLayout() layout.addLayout(widgetLayout) layout.addWidget(buttonBox) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.setWindowTitle("Smart Dialog") def apply(self): class OutOfRangeNumberError(Exception): pass try: value = int(self.valueLineEdit.text()) if value < 0 or value > 100: raise OutOfRangeNumberError("This value is out of range " "from 0 to 100.") except ValueError: QMessageBox.warning(self, "Value is Empty", "This may not be empty") self.valueLineEdit.selectAll() self.valueLineEdit.setFocus() return except OutOfRangeNumberError as e: QMessageBox.warning(self, "Out of Range of number", str(e)) self.valueLineEdit.selectAll() self.valueLineEdit.setFocus() return self.result["label"] = self.textLineEdit.text() self.result["comboBox"] = self.comboBox.currentText() self.result["slider"] = value self.emit(SIGNAL("changed")) class StandardDialog(QDialog): def __init__(self, arg, parent=None): super().__init__(parent) textEditLabel = QLabel("Main 레이블 변경: ") self.textLineEdit = QLineEdit(arg["label"]) valueEditLabel = QLabel("Main 다이얼 변경: ") self.valueLineEdit = QLineEdit(str(arg["dial"])) comboBoxLabel = QLabel("Combo Box(&C): ") self.comboBox = QComboBox() comboBoxLabel.setBuddy(self.comboBox) for item in ["item1", "item2", "item3", "item4", "item5"]: self.comboBox.addItem(item) comboBoxIndex = self.comboBox.findText(arg["comboBox"]) if comboBoxIndex == -1: comboBoxIndex = 0 self.comboBox.setCurrentIndex(comboBoxIndex) self.result = arg.copy() widgetLayout = QFormLayout() widgetLayout.addRow(textEditLabel, self.textLineEdit) widgetLayout.addRow(valueEditLabel, self.valueLineEdit) widgetLayout.addRow(comboBoxLabel, self.comboBox) okButton = QPushButton("확인(&O)") cancelButton = QPushButton("취소") buttonBox = QDialogButtonBox() buttonBox.addButton(okButton, QDialogButtonBox.AcceptRole) buttonBox.addButton(cancelButton, QDialogButtonBox.RejectRole) okButton.setDefault(True) self.connect(buttonBox, SIGNAL("accepted()"), self, SLOT("accept()")) self.connect(buttonBox, SIGNAL("rejected()"), self, SLOT("reject()")) layout = QVBoxLayout() layout.addLayout(widgetLayout) layout.addWidget(buttonBox) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.setWindowTitle("Standard Dialog") def accept(self): class OutOfRangeNumberError(Exception): pass try: value = int(self.valueLineEdit.text()) if value < 0 or value > 100: raise OutOfRangeNumberError("This value is out of range " "from 0 to 100.") except ValueError: QMessageBox.warning(self, "Invalid number format", "This is not a integer") self.valueLineEdit.selectAll() self.valueLineEdit.setFocus() return except OutOfRangeNumberError as e: QMessageBox.warning(self, "Out of Range of number", str(e)) self.valueLineEdit.selectAll() self.valueLineEdit.setFocus() return self.result["label"] = self.textLineEdit.text() self.result["comboBox"] = self.comboBox.currentText() self.result["dial"] = value QDialog.accept(self) def getResult(self): return self.result class DumbDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) textEditLabel = QLabel("Main 레이블 변경: ") self.textLineEdit = QLineEdit("Hello, PyQt!") valueEditLabel = QLabel("Main 값 변경: ") self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) comboBoxLabel = QLabel("Combo Box(&C): ") self.comboBox = QComboBox() comboBoxLabel.setBuddy(self.comboBox) for item in ["item1", "item2", "item3", "item4", "item5"]: self.comboBox.addItem(item) widgetLayout = QFormLayout() widgetLayout.addRow(textEditLabel, self.textLineEdit) widgetLayout.addRow(comboBoxLabel, self.comboBox) widgetLayout.addRow(valueEditLabel, self.slider) okButton = QPushButton("확인(&O)") cancelButton = QPushButton("취소") buttonBox = QDialogButtonBox() buttonBox.addButton(okButton, QDialogButtonBox.AcceptRole) buttonBox.addButton(cancelButton, QDialogButtonBox.RejectRole) okButton.setDefault(True) self.connect(buttonBox, SIGNAL("accepted()"), self, SLOT("accept()")) self.connect(buttonBox, SIGNAL("rejected()"), self, SLOT("reject()")) layout = QVBoxLayout() layout.addLayout(widgetLayout) layout.addWidget(buttonBox) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.setWindowTitle("Dumb Dialog") if __name__ == "__main__": pass
댓글 없음:
댓글 쓰기