2016-07-18 5 views
1

Pyqt4에서 시스템의 확인란을 선택 취소하면 disable_mod 함수를 호출하고 enable_mod를 호출하는 시스템을 구현하려고합니다. 그러나 상태가 변경 되더라도 체크 박스는 시작한 초기 함수를 호출합니다. 이 경우 이미 확인란을 클릭하면 항상 disable_mod 함수를 계속 호출합니다. 왜 이런 일이 일어 났는지 이해가 안되니? 너 나 좀 도와 줄 수 있니?QCheckBox 상태 변경 PyQt4

from PyQt4 import QtCore, QtGui 
from os import walk 
from os.path import join 
import sys 

def list_files_regex(dir): 
    l = [] 
    for (root, dirnames, filenames) in walk(dir): 
     for d in dirnames: 
      list_files_regex(join(root, d)) 
     l.extend(filenames) 
    return l 

directory = "J:/test_pack" 
directory = join(directory, "/mods") 

count = 0 
for y in list_files_regex(directory): 
    print y 
    count += 1 
print count 

class ModEdit(QtGui.QMainWindow): 
    def __init__(self, title, icon, x, y, w, h): 
     super(ModEdit, self).__init__() 
     self.setWindowTitle(title) 
     self.setWindowIcon(QtGui.QIcon(icon)) 
     self.setGeometry(x, y, w, h) 
     self.choices = [] 
     self.init() 

    def init(self): 
     scroll_widget = QtGui.QScrollArea() 
     sub_widget = QtGui.QWidget() 
     v_layout = QtGui.QVBoxLayout() 

     for y in list_files_regex(directory): 
      tmp = QtGui.QCheckBox(y, self) 
      tmp.resize(tmp.sizeHint()) 
      if tmp.text()[len(tmp.text()) - 8: len(tmp.text())] != 'disabled': 
       tmp.setChecked(True) 
      # if tmp.isChecked() == 0: 
      #  tmp.stateChanged.connect(self.enable_mod) 
      # if tmp.isChecked(): 
      #  tmp.stateChanged.connect(self.disable_mod) 
      # v_layout.addWidget(tmp) 
      self.choices.append(tmp) 
     print self.choices 
     for choice in self.choices: 
      v_layout.addWidget(choice) 
      if choice.isChecked(): 
       choice.stateChanged.connect(self.disable_mod) 
      else: 
       choice.stateChanged.connect(self.enable_mod) 
     sub_widget.setLayout(v_layout) 
     scroll_widget.setWidget(sub_widget) 
     self.setCentralWidget(scroll_widget) 
     self.show() 

    def enable_mod(self): 
     print "ENABLE_TEST" 
     print self.choices[1].isChecked() 
    def disable_mod(self): 
     print "DISABLE_TEST" 
     print self.choices[1].isChecked() 

    def test(self): 
     print 'test' 
     for ch in self.choices: 
      if ch.isChecked(): 
       ch.stateChanged.connect(self.disable_mod) 
      else: 
       ch.stateChanged.connect(self.enable_mod) 

class Rename(QtCore.QObject): 
    enable = QtCore.pyqtSignal 
    disable = QtCore.pyqtSignal 

app = QtGui.QApplication(sys.argv) 
ex = ModEdit("Minecraft ModEdit", "ModEdit.png", 64, 64, 640, 480) 
sys.exit(app.exec_()) 

답변

3

문제는 당신이 단지 초기화하는 동안 한 번 체크 박스 stateChanged 신호를 연결하는 것입니다 : 여기에 내 코드입니다. 체크 박스의 상태가 변경되면 신호를 분리하지 않고 올바른 슬롯에 다시 연결합니다.

신호를 stateChanged 신호를 중간 슬롯에 연결해야 확인란을 선택하여 어떤 기능을 호출할지 결정할 수 있습니다. 여러 개의 체크 박스에 동일한 슬롯을 사용하고 있기 때문에 체크 박스를 슬롯에도 전달하는 것이 가장 좋습니다. 우리가 지금 슬롯에있는 확인란을 통과하기 때문에

from functools import partial 

def init(self): 
    ... 
    for tmp in list_of_checkboxes: 
     enable_slot = partial(self.enable_mod, tmp) 
     disable_slot = partial(self.disable_mod, tmp) 
     tmp.stateChanged.connect(lambda x: enable_slot() if x else disable_slot()) 

def enable_mod(self, checkbox): 
    print "ENABLE_TEST" 
    print checkbox.isChecked() 

def disable_mod(self, checkbox): 
    print "DISABLE_TEST" 
    print checkbox.isChecked() 

은 또는, 당신은 단지 하나의 슬롯을 사용하고 너무 많은 설명하기위한 슬롯 내부에

def init(self): 
    ... 
    for tmp in list_of_checkboxes: 
     slot = partial(self.enable_disable_mod, tmp) 
     tmp.stateChanged.connect(lambda x: slot()) 

def enable_disable_mod(self, checkbox): 
    if checkbox.isChecked(): 
     ... 
    else: 
     ... 
+0

감사 체크 박스의 상태를 확인할 수 있습니다! 이 특별한 경우에 람다 함수가 무엇을하는지 말해 주시겠습니까? 나는 람다 함수를 찾았지만이 특별한 경우에는 혼란 스럽다. –

+0

첫 번째 솔루션이 작동합니다. 두 번째 문제는 같은 문제를 겪고 있습니다! –

+0

@DipanjanPatra 두 번째 솔루션의 경우 확인 및 선택 취소를 모두 처리하는 슬롯이 하나만 있음을 알 수 있습니다. 동일한 함수가 두 상태 변경 이벤트 모두에서 호출됩니다. 그것은 의도 된 것입니다. 체크 상태를 기반으로 다른 함수를 호출하는 대신 함수 내에서 체크 박스의 체크 상태를 테스트하여 동일한 함수를 호출하고 실행할 코드를 분할합니다. –