2010-01-05 10 views
1

J'ai une famille de classes (basées sur la même classe parente) qui sont des cellules de données dans un QTableWidget (elles sont donc toutes dérivées de QItemDelegate). J'essaye de créer un signal que ces classes peuvent passer au contrôleur pour communiquer des changements de données.PyQt4 Signalisation entre classes

Je ne trouve pas la bonne combinaison (malgré beaucoup d'expérimentation et de lecture) qui a 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 Sous-classe (seulement les parties pertinentes - LMK si plus d'information nécessaire):

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 
    .... 

est ici la partie pertinente de mon classe 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 «objet C++ sous-jacent a été supprimé». J'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) 

Des suggestions? Je n'ai pas besoin d'utiliser cette méthode, mais j'ai plutôt besoin d'un moyen d'extraire ces données des contrôles individuels.

TIA

Mike

Répondre

1

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 
+0

Pour ce que ça vaut, j'ai couru dans la même erreur et cela a été utile. – acrosman

0

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_() 
+0

Jesse - Ce qui est bon, mais chaque classe est dans un fichier séparé. J'essayais d'utiliser des signaux Qt pour couvrir les classes. –

+0

Vous pouvez facilement diviser les classes en fichiers séparés dans mon exemple. Je ne pense pas qu'il y ait besoin de signaux Qt. Je vais éditer mon exemple ... –