2016-07-18 15 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信号を1回だけ接続するということです。チェックボックスの状態が変わったら、信号を切断して正しいスロットに再接続しません。

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

第1の解決策が働く。第2のものは同じ問題を抱えています! –

+0

@DipanjanPatra第2の解決策として、チェックとアンチェックの両方を処理するスロットが1つしかないことに注意してください。両方の状態変更イベントで同じ関数が呼び出されます。それは意図されています。チェック状態に基づいて別の関数を呼び出すのではなく、関数内のチェックボックスのチェック状態をテストすることによって、同じ関数を呼び出して実行するコードを分割します。 –