PyQt4 entre les classes de signalisation
Question
J'ai une famille de classes (en fonction de la même classe parente) qui sont des cellules de données dans un QTableWidget (ils sont tous issus de QItemDelegate).
Je suis en train de créer un signal que ces classes peuvent laisser passer au contrôleur pour communiquer les changements de données.
Je ne peux pas trouver la bonne combinaison (malgré beaucoup d'expérimentation et de la lecture) qui accompli. Voici ma structure de classe:
Classe de base:
class Criteria(QItemDelegate):
def bind(self, update):
self.connect(self,SIGNAL("criteriaChange(int, int, QVariant)"),update)
def emitCommitData(self):
self.emit(SIGNAL("criteriaChange(int, int, QVariant)"), self.Row, self.Col, self.getValue())
Exemple de sous-classe (seulement les parties pertinentes - LMK si nécessaire plus d'informations):
class YesNo(Criteria):
....
def createEditor(self, parent, option, index):
self.comboBox = QComboBox(parent)
for item in self.getChoices():
self.comboBox.addItem(item)
self.comboBox.activated.connect(self.emitCommitData)
return self.comboBox
....
Voici la partie pertinente de ma classe de maître:
@pyqtSlot(int, int, QVariant, name='criteriaChanged')
def setItem(self, row, col, item):
print row, col, item.toString() # TODO: Remove when tested
self.Data[row][col] = item.toString()
def addCriteria(self, row, cname, ctype):
self.setDirty()
c = YesNo(cname, "YesNo")
c.bind(self.setItem)
Le code ci-dessus donne un « sous-jacent objet C ++ a été supprimé ». Je l'ai essayé ceci:
def addCriteria(self, row, cname, ctype):
self.setDirty()
c = YesNo(cname, "YesNo")
self.connect(c,SIGNAL("criteriaChange(int, int, QVariant)"),self.setItem)
Toutes les suggestions? Je n'ai pas à utiliser cette méthode, mais plutôt besoin d'un moyen d'obtenir que les données sur les contrôles individuels.
TIA
Mike
La solution
Je suis vraiment gêné à ce sujet. Espérons que cela aidera quelqu'un d'autre.
Je n'ai pas appelé l'initialisation Qt pour l'objet approprié:
class YesNo(Criteria):
def __init__(self, name, ctype):
Criteria.__init__(self) # <<<<----- This was missing before
self.Name = name
self.Index = ctype
et
class Criteria(QItemDelegate):
def __init__(self):
QItemDelegate.__init__(self) # <<<<----- This was missing before
Autres conseils
criteria.py
def criteria_change(row, col, new_value):
print "change at", row, col, "new_value:", new_value
class Criteria:
def __init__(self, row, col):
self.row, self.col = row, col
def on_change(self):
criteria_change(self.row, self.col, self.value())
yes_no_maybe.py
from PyQt4.QtGui import *
from criteria import Criteria
class YesNoMaybe(Criteria):
def create_editor(self):
group_box = QGroupBox()
layout = QVBoxLayout()
group_box.setLayout(layout)
self.buttons = []
for s in ["yes", "no", "maybe"]:
button = QRadioButton(s)
self.buttons.append(button)
layout.addWidget(button)
button.toggled.connect(self.on_toggle)
return group_box
#
def on_toggle(self, is_now_on):
if is_now_on:
self.on_change()
def value(self):
for button in self.buttons:
if button.isChecked():
return button.text()
#
yes_no.py
from PyQt4.QtGui import QComboBox
from criteria import Criteria
class YesNo(Criteria):
def create_editor(self):
combo_box = self.combo_box = QComboBox()
for s in ["red", "blue"]:
combo_box.addItem(s)
combo_box.activated.connect(self.on_change)
return combo_box
#
def value(self):
return self.combo_box.currentText()
#
main.py
import sys
from PyQt4.QtGui import *
from yes_no_maybe import YesNoMaybe
from yes_no import YesNo
app = QApplication(sys.argv)
table_classes = [[YesNo, YesNo],
[YesNoMaybe, YesNoMaybe]]
table = QTableWidget(len(table_classes), len(table_classes[0]))
table.criteria = []
for r, cls_row in enumerate(table_classes):
criteria_row = []
table.criteria.append(criteria_row)
for c, criteria_cls in enumerate(cls_row):
criteria = criteria_cls(r, c)
criteria_row.append(criteria)
table.setCellWidget(r, c, criteria.create_editor())
table.setRowHeight(1, 100)
table.show()
app.exec_()