본문 바로가기
PyQt5_

Signals & Slots

by 자동매매 2023. 3. 10.
GUI 응용 프로그램을 만들 일반적으로 무언가하기를 원합니다! 우리에게 필요한 것은 버튼을 누르 동작을 무언가 일어나 하는 것과 연결하는 방법입니다.
Qt에서 이것은 신호(signal) 슬롯(slot) 의해 제공됩니다.

Signal

신호는 어떤 일이 발생할 위젯에서 방출(emit)되는 신호입니다.
버튼을 누르는 것부터 입력 상자의 텍스트가 변경되고 창의 텍스트가 변경되는 것까지 다양한 것이 있습니다. 많은 신호가 사용자 작업에 의해 시작되지만 이는 규칙이 아닙니다.

신호는 어떤 일이 일어나고 있는지 알리는 것 외에도 데이터를 보내 일어난 일에 대한 추가 컨텍스트를 제공 수도 있습니다.

Slot

슬롯은 Qt 신호 receiver 사용하는 이름입니다.
파이썬에서는 어플리케이션의 모든 함수(또는 메소드)를 슬롯으로 사용할 수 있습니다

단순히 신호를 슬롯에 연결하기만 하면 됩니다.

신호가 데이터를 보내면 수신 기능도 해당 데이터를 수신합니다.

많은 Qt 위젯에는 자체 내장 슬롯이 있어 Qt 위젯을 직접 연결할 있습니다.

 

from PyQt6.QtWidgets import (
    QApplication,
    QMainWindow,
    QPushButton,
)  # <1>

import sys


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()  # <2>

        self.setWindowTitle("My App")

        button = QPushButton("Press Me!")
        button.setCheckable(True)
        button.clicked.connect(self.the_button_was_clicked)

        # Set the central widget of the Window.
        self.setCentralWidget(button)

    def the_button_was_clicked(self):
        print("Clicked!")


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

 

 

Receiving data

신호가 방금 일어난 일에 대한 많은 정보를 제공하기 위해 데이터를 보낼 수도 있다고 이미 들었습니다.

.clicked 신호도 예외는 아니며 버튼에 대한 checked(또는 toggled) 상태도 제공합니다

 

- 기본 signal이 아니므로 설정 필요( 예 setCheckable(True)  )

- 다음 예에서는 checkstate 출력하는 번째 슬롯을 추가합니다.

  clicked signal  - > check state 데이터 전달( checked )

 

 

# checked가 False로 시작

import sys

from PyQt6.QtWidgets import (
    QApplication,
    QMainWindow,
    QPushButton,
)  # <1>


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()  # <2>

        self.setWindowTitle("My App")

        button = QPushButton("Press Me!")
        button.setCheckable(True)
        button.clicked.connect(self.the_button_was_clicked)
        button.clicked.connect(self.the_button_was_toggled)

        # Set the central widget of the Window.
        self.setCentralWidget(button)

    def the_button_was_clicked(self):
        print("Clicked!")

    def the_button_was_toggled(self, checked):
        print("Checked?", checked)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

 

Storing data

# checked상태를 True로 설정하여 시작

import sys

from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.button_is_checked = True  # <1>

        self.setWindowTitle("My App")

        button = QPushButton("Press Me!")
        button.setCheckable(True)
        button.clicked.connect(self.the_button_was_toggled)
        button.setChecked(self.button_is_checked)  # <2>

        # Set the central widget of the Window.
        self.setCentralWidget(button)

    def the_button_was_toggled(self, checked):
        self.button_is_checked = checked  # <3>

        print(self.button_is_checked)

 

위와 동일 기능

import sys

from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.button_is_checked = True

        self.setWindowTitle("My App")

        self.button = QPushButton("Press Me!")  # <1>
        self.button.setCheckable(True)
        self.button.released.connect(
            self.the_button_was_released
        )  # <2>
        self.button.setChecked(self.button_is_checked)

        # Set the central widget of the Window.
        self.setCentralWidget(self.button)

    def the_button_was_released(self):
        self.button_is_checked = self.button.isChecked()  # <3>

        print(self.button_is_checked)



app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()
 

released signal는 버튼에서 손을 떼면 발생하지만 checked상태는 전송되지 않습니다. .isChecked()버튼의 checked 상태를 반환합니다.

 

Changing the interface

conssole 아닌 직접 widget 속성을 변경하여 직접 표시 - PushButton text toggle 구현

from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton
import sys

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        self.button = QPushButton("Press Me!")  # <1>
        self.button.setCheckable(True)        
        self.button.clicked.connect(self.the_button_was_clicked)

        # Set the central widget of the Window.
        self.setCentralWidget(self.button)

    def the_button_was_clicked(self,checked):
        if not checked:
            self.button.setText("Press Me!")  # <2>
        else:
            self.button.setText("")

        self.setWindowTitle("My Oneshot App")

app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

 

버튼 비사용 설정

self.button.setEnabled(False)
동일 기능
self.button.setDisable(True)

 

Note  첫째, 제목을 설정할 windowTitleChanged 신호가 항상 방출되는 것은 아닙니다.
                   신호는 타이틀이 이전 타이틀에서 변경된 경우에만 발생합니다.
                   동일한 제목을 여러 설정하면 신호가 처음에만 발생합니다.

                   앱에서 신호를 사용할 놀라지 않도록 신호가 발생하는 조건을 다시 확인하는 것이 중요합니다.

         둘째, 효과를 트리거한 것과 효과를 분리하는 것은 GUI 응용 프로그램을 빌드할 주요 고려 사항 하나입니다.

 

 

Connecting widgets together directly

지금까지 위젯 신호를 Python 메서드에 연결하는 예제를 살펴보았습니다. 위젯에서 신호가 발생하면 Python 메서드가 호출되고 수신됩니다.

그러나  신호를 처리하기 위해 항상 Python 함수를 사용할 필요는 없으며 Qt 위젯을 서로 직접 연결할 수도 있습니다.

 

대부분의 Qt 위젯에는 사용 가능한 슬롯이있어 수신하는  것과 동일한 유형을 방출하는 모든 신호를 연결할   있습니다

from PyQt6.QtWidgets import (
    QApplication,
    QMainWindow,
    QLabel,
    QLineEdit,
    QVBoxLayout,
    QWidget,
)

import sys


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("My App")

        self.label = QLabel()

        self.input = QLineEdit()
        self.input.textChanged.connect(self.label.setText)  # <1>

        layout = QVBoxLayout()  # <2>
        layout.addWidget(self.input)
        layout.addWidget(self.label)

        container = QWidget()
        container.setLayout(layout)

        # Set the central widget of the Window.
        self.setCentralWidget(container)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

 

'PyQt5_' 카테고리의 다른 글

Layouts  (0) 2023.03.11
Widgets  (0) 2023.03.10
Sizing windows and widgets  (0) 2023.03.10
빈 창  (0) 2023.03.10
index  (0) 2023.03.10

댓글