[PYTHON] 람다 식을 사용하여 pyqt의 슬롯 연결
PYTHON람다 식을 사용하여 pyqt의 슬롯 연결
람다 함수로 슬롯을 연결하려고하는데 예상대로 작동하지 않습니다. 아래의 코드에서 처음 두 버튼을 올바르게 연결하는 데 성공했습니다. 루프로 연결되는 두 번째 두 경우에는 잘못되었습니다. 나보다 먼저 누군가가 같은 질문 (Qt - 람다를 사용한 인수를 가진 연결 슬롯)을 가지고 있지만,이 솔루션은 나를 위해 작동하지 않습니다. 30 분 동안 내 화면을 쳐다보고 있었지만 코드가 어떻게 다른지 알 수는 없습니다.
class MainWindow(QtGui.QWidget):
def __init__(self):
super(QtGui.QWidget, self).__init__()
main_layout = QtGui.QVBoxLayout(self)
# Works:
self.button_1 = QtGui.QPushButton('Button 1 manual', self)
self.button_2 = QtGui.QPushButton('Button 2 manual', self)
main_layout.addWidget(self.button_1)
main_layout.addWidget(self.button_2)
self.button_1.clicked.connect(lambda x:self.button_pushed(1))
self.button_2.clicked.connect(lambda x:self.button_pushed(2))
# Doesn't work:
self.buttons = []
for idx in [3, 4]:
button = QtGui.QPushButton('Button {} auto'.format(idx), self)
button.clicked.connect(lambda x=idx: self.button_pushed(x))
self.buttons.append(button)
main_layout.addWidget(button)
def button_pushed(self, num):
print 'Pushed button {}'.format(num)
첫 번째 두 버튼을 누르면 '푸시 버튼 1'과 '푸시 버튼 2'가 나오고 나머지 두 버튼은 모두 '푸시 버튼 거짓'이됩니다.
나는 또한 람다 메커니즘을 완전히 이해하지 못했다. 정확히 무엇이 연결 되나요? 람다에 의해 생성 된 함수에 대한 포인터 (매개 변수가 치환 됨)이거나 신호가 발생할 때마다 평가되는 람다 함수입니까?
해결법
-
==============================
1.QPushButton.clicked 신호는 단추의 상태를 나타내는 인수를 내 보냅니다. 람다 슬롯에 연결하면 idx에 할당하는 선택적 인수가 버튼의 상태로 덮어 쓰여집니다.
QPushButton.clicked 신호는 단추의 상태를 나타내는 인수를 내 보냅니다. 람다 슬롯에 연결하면 idx에 할당하는 선택적 인수가 버튼의 상태로 덮어 쓰여집니다.
대신에 다음과 같이 연결하십시오.
button.clicked.connect(lambda state, x=idx: self.button_pushed(x))
이렇게하면 단추 상태가 무시되고 올바른 값이 메서드에 전달됩니다.
-
==============================
2.조심해! 자기 자신에 대한 참조로 람다 슬롯에 신호를 연결하자 마자 위젯은 가비지 수집되지 않을 것입니다! lambda가 위젯에 대한 또 다른 수집 할 수없는 참조로 클로저를 생성하기 때문입니다.
조심해! 자기 자신에 대한 참조로 람다 슬롯에 신호를 연결하자 마자 위젯은 가비지 수집되지 않을 것입니다! lambda가 위젯에 대한 또 다른 수집 할 수없는 참조로 클로저를 생성하기 때문입니다.
따라서, self.someUIwidget.someSignal.connect (람다 피 : self.someMethod (p))는 매우 악합니다 :)
-
==============================
3.나는 정직하게 람다의 당신의 사용과 함께 잘못되고있는 것이 여기에서도 확실하지 않다. idx (자동 단추를 설정할 때 루프 인덱스)가 범위를 벗어나 더 이상 적절한 값을 포함하지 않기 때문이라고 생각합니다.
나는 정직하게 람다의 당신의 사용과 함께 잘못되고있는 것이 여기에서도 확실하지 않다. idx (자동 단추를 설정할 때 루프 인덱스)가 범위를 벗어나 더 이상 적절한 값을 포함하지 않기 때문이라고 생각합니다.
하지만 당신이 그렇게 할 필요는 없다고 생각합니다. 람다를 사용하는 유일한 이유는 button_pushed ()에 인수를 전달하여 어떤 버튼인지 식별 할 수 있기 때문입니다. 버튼이 신호를 보낸 버튼을 식별하는 button_pushed () 슬롯에서 호출 할 수있는 sender () 함수가 있습니다.
제가 생각하기에 당신이 뭘 쏘고 있는지를 보여주는 예가 있습니다 :
from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * import sys class MainWindow(QWidget): def __init__(self): super(QWidget, self).__init__() main_layout = QVBoxLayout(self) self.buttons = [] # Works: self.button_1 = QPushButton('Button 1 manual', self) main_layout.addWidget(self.button_1) self.buttons.append(self.button_1) self.button_1.clicked.connect(self.button_pushed) self.button_2 = QPushButton('Button 2 manual', self) main_layout.addWidget(self.button_2) self.buttons.append(self.button_2) self.button_2.clicked.connect(self.button_pushed) # Doesn't work: for idx in [3, 4]: button = QPushButton('Button {} auto'.format(idx), self) button.clicked.connect(self.button_pushed) self.buttons.append(button) main_layout.addWidget(button) def button_pushed(self): print('Pushed button {}'.format(self.buttons.index(self.sender())+1)) app = QApplication(sys.argv) w = MainWindow() w.show() sys.exit(app.exec_())
from https://stackoverflow.com/questions/35819538/using-lambda-expression-to-connect-slots-in-pyqt by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 파이썬, TypeError : unshashable 타입 : 'list' (0) | 2018.10.08 |
---|---|
[PYTHON] 내 전역 변수에 파이썬으로 할당 할 수없는 이유는 무엇입니까? (0) | 2018.10.08 |
[PYTHON] 초심자 파이썬 : 동일한 파일 읽기 및 쓰기 (0) | 2018.10.08 |
[PYTHON] 파이썬을 사용하여 문자열에서 URL을 추출하는 가장 깨끗한 방법은 무엇입니까? (0) | 2018.10.08 |
[PYTHON] 파이썬 범위 [duplicate] (0) | 2018.10.08 |