2

我正在尝试在 PyQt4 中实现一个系统,其中取消选中复选框将调用函数 disable_mod 并检查它将调用 enable_mod。但即使状态正在改变,复选框也会调用它们开始使用的初始函数。对于这种情况,如果单击了已选中的框,它将始终继续调用 disable_mod 函数!我不明白为什么会这样?你们能帮我一下吗?这是我的代码:

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_())
4

1 回答 1

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:
        ...
于 2016-07-18T18:02:37.483 回答