반응형

clicked.connect으로 호출되는 함수의 인자로 콤보박스의 인덱스와 어떤 값을 전달하고 싶다.

 

코드 구현 중점

clicked.connect의 함수 값 전달 방법을 포인터로 넘겨준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# currentIndex()는 원래 콤보 박스의 현재 인덱스를 반환한다.
# 그러나 그렇게 하면 clicked.connect할 때의 반환 값이 들어가기 때문에
# 함수 포인터 형태로 전달한다.
self._button_adds[idx].clicked.connect(      self._cb_add_plot(self._cbs[idx].currentIndex, idx))
self._button_removes[idx].clicked.connect(   self._cb_remove_plot(self._cbs[idx].currentIndex, idx))
 
# 함수 포인터(cb_idx)와 인자(idx)를 전달한다.
# 그러나 내부에는 한번 wrapping하여 사용한다.
def _cb_add_plot(self, cb_idx, idx):
    def _add_plot():
        print('Add data{:d} to line.{:d}'.format(cb_idx(), idx))
    return _add_plot
def _cb_remove_plot(self, cb_idx, idx):
    def _remove_plot():
        print('Remove data.{:d} to line.{:d}'.format(cb_idx(), idx))
    return _remove_plot
cs

 

콜백 함수는 위와 같이 내부 함수를 정의하여서 썼는데,

아래와 같이 쓰면.. 안된다.

clicked.connect했을 때 넣었던 값이 나오기 때문이다. 현재 idx가 아니라..

1
2
3
# 이렇게 쓰면 인자(idx)에 clicked.connect 했을 때 넣었던 엉뚱한 idx 값이 들어간다.
def _cb_add_plot(self, cb_idx, idx):
    print('Add data{:d} to line.{:d}'.format(cb_idx(), idx))
cs

 

코드 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import time
import sys, os
 
from pubsub import pub
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QPushButton, QLabel, QComboBox, qApp
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QVBoxLayout
 
class MakerTester(QMainWindow):
    def __init__(self):
        super().__init__()
 
        self._cbs = list()
        self._button_adds = list()
        self._button_removes = list()
        for idx in range(0,3):
            cb = QComboBox(self)
            cb.setGeometry(1010 + 50*idx, 9040)
            cb.addItem("1")
            cb.addItem("2")
            cb.addItem("3")
            cb.addItem("4")
            cb.addItem("5")
            self._cbs.append(cb)
 
            self._button_adds.append(self._get_button(   name="Add",      parent=self, geo=[11010 + 50*idx, 9040]))
            self._button_removes.append(self._get_button(name="Remove",   parent=self, geo=[21010 + 50*idx, 9040]))
            # combobox의 값은 함수 포인터로 전달하고, 내부에서 호출하도록 하자.
            # QCombobox.currentIndex() 으로 인덱스를 얻을 수 있는데
            # 괄호() 를 없에면 함수 포인터처럼 보낼 수 있다.
            self._button_adds[idx].clicked.connect(      self._cb_add_plot(self._cbs[idx].currentIndex, idx))
            self._button_removes[idx].clicked.connect(   self._cb_remove_plot(self._cbs[idx].currentIndex, idx))
        
        self._set_window()
 
    def _set_window(self):
        self.setWindowTitle('My First Application')
        self.move(300300)
        self.resize(500300)
        self.show()
 
    def _get_button(self, name, parent, geo, callback=None):
        button = QPushButton(name, parent)
        button.setCheckable(False)
        button.setDisabled(False)
        button.setGeometry(geo[0], geo[1], geo[2], geo[3])
        if(callback != None): button.clicked.connect(callback)
        return button
 
    def _cb_add_plot(self, cb_idx, idx):
        def _add_plot():
            print('Add data{:d} to line.{:d}'.format(cb_idx(), idx))
        return _add_plot
 
    def _cb_remove_plot(self, cb_idx, idx):
        def _remove_plot():
            print('Remove data.{:d} to line.{:d}'.format(cb_idx(), idx))
        return _remove_plot
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    Tester = MakerTester()
    app.exec()
cs

 

결과물

콤보 박스를 변경하고 Add / Remove를 누르면 몇 번째 줄인지와 해당 콤보박스의 인덱스를 출력한다.

 

Reference

[1] stack overflow, "How to pass arguments to functions by the click of button in PyQt?",  https://stackoverflow.com/questions/6784084/how-to-pass-arguments-to-functions-by-the-click-of-button-in-pyqt

 

EOF

728x90

+ Recent posts