ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Day 9. PyQt5 (Dialogs)
    <개인공부> - IT/[Python] 2021. 3. 30. 04:52
    반응형

    Dialogs는 GUI 구성요소 중 user와 communicate할 수 있도록 해주는 구성요소이다. 파일을 열고 저장한다던가 글자의 색을 바꾼다던가 등의 main UI와는 별도로 존재하는 windows를 dialogs라 한다. 조금더 기술적인 용어로 접근하면 dialogs는 modal (or blocking) windows이다. 다시 말해서, dialogs가 실행되면 main UI는 해당 dialogs가 닫힐 때까지 사용할 수 없는 상태가 된다. Qt의 dialog box는 QDialog class에 의해 handling된다. 따라서, 단순한 대화창을 만들고 싶다면 QDialog 객체를 QMainWindow에 전달하면 된다. 

     

    import sys
    
    from PyQt5.QtWidgets import (
        QApplication, 
        QMainWindow,
        QLabel,
        QDialog,
        QPushButton
    )
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("My App")
    
            button = QPushButton("Press me for a dialog!")
            button.clicked.connect(self.button_clicked)
            self.setCentralWidget(button)
        
        def button_clicked(self, s):
            print("click", s)
    
            dlg = QDialog(self)
            dlg.setWindowTitle("HELLO!")
            dlg.exec_()
    
    app = QApplication(sys.argv)
    
    window = MainWindow()
    window.show()
    
    app.exec_()

     

    위의 코드를 수행하고 버튼을 눌러주게 되면 작은 빈 dialog가 생성된다. 여기서 기억하고 넘어가야 할 부분은 언제나 단 하나의 Qt event loop만 수행가능하다는 점이다. dialog가 팝업되면 main application의 기능 (여기서는 버튼 누르기)이 block된다. (물론, multithreading 기능이 존재하나 추후 정리해보고자 한다)

     

    아래 코드는 QDialog를 customizing 해보았다. QDialog의 subclass인 CustomDialog를 정의했다. 물론 해당 설정을 사용하고자 한다면 QMainWindow에서 우리가 정의한 CustomDialog를 호출해 객체를 생성해야 한다는 점. 또한, QDialogButtonBox를 이용해서 dialog에서 user와 interaction할 수 있는 버튼을 생성했다. 물론, 각각의 버튼이 정확한 기능을 수행하려면 각 signal을 잘 연결해주어야 한다. .accepted를 .accept()와 .rejected를 .reject()와 연결한 것이 그 예이다. 코멘트로 misc setting이라고 설정한 부분이 있다. 이와 같이 설정하지 않으면 dialog 윈도우는 main window와 떨어진채로 팝업된다. 이는 user에게 보다 편리함을 제공하고자 우리가 생성하는 main window를 parent로 전달하게 되면 팝업되는 dialog는 main window의 중앙에 정렬되어 팝업된다.

    import sys
    
    from PyQt5.QtCore import Qt
    
    from PyQt5.QtWidgets import (
        QApplication, 
        QMainWindow,
        QToolBar,
        QLabel,
        QDialog,
        QPushButton,
        QDialogButtonBox,
        QVBoxLayout
    )
    
    class CustomDialog(QDialog):
    
        # Misc setting to pop up right in the middle of the parent window
        def __init__(self, parent=None):
            
            # Misc setting to pop up right in the middle of the parent window
            super().__init__(parent)
            self.setWindowTitle("HELLO!")
            QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
            self.buttonBox = QDialogButtonBox(QBtn)
            self.buttonBox.accepted.connect(self.accept)
            self.buttonBox.rejected.connect(self.reject)
            self.layout = QVBoxLayout()
            message = QLabel("Something happened, is that OK?")
            self.layout.addWidget(message)
            self.layout.addWidget(self.buttonBox)
            self.setLayout(self.layout)
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("My App")
    
            button = QPushButton("Press me for a dialog!")
            button.clicked.connect(self.button_clicked)
            self.setCentralWidget(button)
        
        def button_clicked(self, s):
            print("click", s)
    
            # Misc setting to pop up right in the middle of the parent window
            dlg = CustomDialog(self)
    
            if dlg.exec_():
                print("Success!")
            else:
                print("Cancel!")
            
    
    app = QApplication(sys.argv)
    
    window = MainWindow()
    window.show()
    
    app.exec_()

     

    앞서 작성된 코드처럼 내가 dialogs를 구성할 수도 있지만 Qt에서는 built-in message dialog class인 QMessageBox를 제공한다. 우선 두 가지 코드를 간단히 비교해보도록 하자.

     

    # 1. Usage of QMessageBox
    dlg = QMessageBox(self)
    dlg.setWindowTitle("I have a question!")
    dlg.setText("This is a question dialog")
    dlg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
    dlg.setIcon(QMessageBox.Question)
    button = dlg.exec_()
    
    # 2. Usage of QMessageBox
    button = QMessageBox.question(self, "Question dialog", "The
    longer message")

    동일한 dialogs가 팝업되는 코드이지만 두 번째 방법을 이용하면 한 줄로 동일 기능을 구현할 수 있다. 참고로 첫 번째 방법은 QMessageBox의 객체를 생성 후 관련 세부설정을 한 뒤 exec()를 호출하지만 built-in .question() method를 이용해도 동일한 결과를 볼 수 있다는 점.

     

     

    1. Reference book: "Create GUI Applications with Python & Qt5: The hands-on guide to making apps with Python"

    반응형

    '<개인공부> - IT > [Python]' 카테고리의 다른 글

    Python (pass, continue, and break)  (0) 2021.07.20
    Subprocess 모듈이용하기  (0) 2021.04.15
    Day 8. PyQt5 (Actions, Toolbars, Menus)  (0) 2021.03.20
    Day 7. PyQt5 (Layouts)  (0) 2021.03.19
    Day 6. PyQt5 (QSpinBox, QSlider, QDial)  (0) 2021.03.18
Designed by Tistory.