Pergunta

Eu tenho uma família de classes (com base na mesma classe pai) que são dados células em uma QTableWidget (assim eles são todos derivados do QItemDelegate).

Eu estou tentando criar um sinal de que essas classes podem passar para o controlador para comunicar as alterações de dados.

Não consigo encontrar a combinação certa (apesar de muita experimentação e leitura) que realizou. Aqui está minha estrutura de classe:

Class 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())

Exemplo Sub-classe (apenas as partes relevantes - LMK se mais informações necessário):

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

Aqui está a parte relevante da minha master class:

@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)

O código acima dá um "objeto Subjacente C ++ ter sido eliminada". Eu tentei isso:

def addCriteria(self, row, cname, ctype):
    self.setDirty()
    c = YesNo(cname, "YesNo")
    self.connect(c,SIGNAL("criteriaChange(int,  int, QVariant)"),self.setItem)

Todas as sugestões? Eu não tenho de usar este método, mas precisa encontrar uma maneira de obter esses dados para fora dos controles individuais.

TIA

Mike

Foi útil?

Solução

Estou realmente envergonhado com isso. Esperemos que isto irá ajudar alguém.

Eu não chamei a inicialização Qt para o objeto apropriado:

class YesNo(Criteria):
    def __init__(self,  name,  ctype):
        Criteria.__init__(self)            # <<<<----- This was missing before
        self.Name = name
        self.Index = ctype

e

class Criteria(QItemDelegate):
    def __init__(self):
        QItemDelegate.__init__(self)       # <<<<----- This was missing before

Outras dicas

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_()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top