본문 바로가기
Python Library/PySide

[PySide] Context menus

by goatlab 2022. 6. 13.
728x90
반응형
SMALL

Context menus

 

상황에 맞는 메뉴는 일반적으로 창을 마우스 오른쪽 버튼으로 클릭할 때 나타나는 작은 상황에 맞는 메뉴이다. Qt는 이러한 메뉴 생성을 지원하며 위젯에는 이를 트리거하는 데 사용되는 특정 이벤트가 있다. 만약, contextMenuEventa의 QMainWindow를 가로챈다고 가정한다. 이 이벤트는 상황에 맞는 메뉴가 표시될 때마다 시작되고 typeevent의 단일 값이 QContextMenuEvent에 전달된다.

 

이벤트를 가로채기 위해 객체 메서드를 같은 이름의 새 메서드로 재정의하면 된다. 따라서, 이 경우 이름을 사용하여 하위 클래스 MainWindow에 메서드를 만들 수 있으며 contextMenuEvent이 유형의 모든 이벤트를 수신한다.

 

import sys

from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QMenu

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

    def contextMenuEvent(self, e):
        context = QMenu(self)
        context.addAction(QAction("test 1", self))
        context.addAction(QAction("test 2", self))
        context.addAction(QAction("test 3", self))
        context.exec_(e.globalPos())

app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec_()

 

위의 코드를 실행하고 창 내에서 마우스 오른쪽 버튼을 클릭하면 컨텍스트 메뉴가 나타난다. 메뉴 작업의 triggered 슬롯을 평소와 같이 설정할 수 있다 (그리고 메뉴 및 도구 모음에 대해 정의된 작업을 재사용).

 

완전성을 위해 실제로 상황에 맞는 메뉴를 만드는 신호 기반 접근 방식이 있다.

 

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

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.on_context_menu)

    def on_context_menu(self, pos):
        context = QMenu(self)
        context.addAction(QAction("test 1", self))
        context.addAction(QAction("test 2", self))
        context.addAction(QAction("test 3", self))
        context.exec_(self.mapToGlobal(pos))

 

이벤트 계층

 

PySide에서 모든 위젯은 Python 객체 계층과 Qt 레이아웃 계층이라는 두 가지 고유한 계층의 일부이다. 이벤트에 응답하거나 무시하는 방법은 UI가 작동하는 방식에 영향을 줄 수 있다.

 

Python 상속 포워딩

 

종종 이벤트를 가로채서 무언가를 하고 싶지만 여전히 기본 이벤트 처리 동작을 트리거하고 싶을 수 있다. 객체가 표준 위젯에서 상속된 경우 기본적으로 합리적인 동작이 구현될 수 있다. super()를 사용하여 상위 구현을 호출하여 이를 트리거할 수 있다.

 

def mousePressEvent(self, event):
    print("Mouse pressed!")
    super(self, MainWindow).contextMenuEvent(event)

 

이벤트는 계속해서 정상적으로 작동하지만 방해하지 않는 일부 동작을 추가했다.

 

레이아웃 포워딩

 

애플리케이션에 위젯을 추가 하면 레이아웃에서 다른 상위 위젯도 가져 온다. 위젯의 부모는 parent()를 호출하여 찾을 수 있다. QMenu경우에 따라 QMenu 또는 QDialog와 같이 이러한 상위 항목을 수동으로 지정하는 경우가 종종 있다. 예를 들어, 기본 창에 위젯을 추가하면 기본 창이 위젯의 ​​부모가 된다.

 

UI와의 사용자 상호 작용을 위해 이벤트가 생성되면 이러한 이벤트는 UI의 최상위 위젯으로 전달된다. 따라서, 창에 버튼이 있고 버튼을 클릭하면 버튼이 먼저 이벤트를 수신한다.

 

첫 번째 위젯이 이벤트를 처리할 수 없거나 처리하지 않기로 선택하면 이벤트가 상위 위젯으로 버블링 (bubbling)되고 차례가 주어진다.  버블링은 이벤트가 처리되거나 기본 창에 도달할 때까지 중첩된 위젯까지 계속된다.

 

고유한 이벤트 핸들러에서 이벤트를 처리된 호출 .accept()로 표시하도록 선택할 수 있다.

 

    class CustomButton(QPushButton)
        def mousePressEvent(self, e):
            e.accept()

 

또는 이벤트 개체 .ignore()를 호출하여 처리되지 않은 것으로 표시할 수 있다. 이 경우 이벤트는 계층 구조를 계속 버블링한다.

 

    class CustomButton(QPushButton)
        def event(self, e):
            e.ignore()

 

위젯이 이벤트에 투명하게 나타나도록 하려면 실제로 어떤 식으로든 응답한 이벤트를 안전하게 무시할 수 있다. 마찬가지로, 응답하지 않는 이벤트를 허용하지 않도록 선택할 수 있다.

728x90
반응형
LIST

'Python Library > PySide' 카테고리의 다른 글

[PySide] 위젯 (QLabel, QCheckBox) (2)  (0) 2022.06.13
[PySide] 위젯 (1)  (0) 2022.06.13
[PySide] 이벤트  (0) 2022.06.13
[PySide] 위젯 연결하기  (0) 2022.06.13
[PySide] 인터페이스 변경  (0) 2022.06.13