Python QCheckBox状态更改PyQt4
我正在尝试在PyQt4中实现一个系统,其中取消选中复选框将调用函数disable_mod,选中它将调用enable_mod。但是,即使状态正在更改,复选框也会调用它们开始使用的初始函数。在这种情况下,如果已经选中了一个复选框,它会一直调用disable_mod函数!我不明白为什么会这样?你们能帮我一点忙吗?这是我的密码:Python QCheckBox状态更改PyQt4,python,qt,pyqt,qcheckbox,Python,Qt,Pyqt,Qcheckbox,我正在尝试在PyQt4中实现一个系统,其中取消选中复选框将调用函数disable_mod,选中它将调用enable_mod。但是,即使状态正在更改,复选框也会调用它们开始使用的初始函数。在这种情况下,如果已经选中了一个复选框,它会一直调用disable_mod函数!我不明白为什么会这样?你们能帮我一点忙吗?这是我的密码: from PyQt4 import QtCore, QtGui from os import walk from os.path import join import sys
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_())
问题在于,在初始化过程中,您只连接了一次复选框
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:
...
谢谢你解释这么多!你能告诉我lambda函数在这种特殊情况下的作用吗?我查过lambda函数,但在这个特殊情况下我感到困惑。第一种解决方案有效。第二个也有同样的问题@对于第二个解决方案,请注意,只有一个插槽同时处理检查和取消检查。对两个状态更改事件调用相同的函数;这是有意的。与基于检查状态调用不同的函数不同,您可以调用相同的函数,并通过测试函数内复选框的检查状态来拆分要运行的代码。