2012-03-13 5 views
10

He creado una casilla de verificación que también es QTreeWidgetItem usando el siguiente código.¿Es posible crear una señal para cuando se active una casilla de verificación QTreeWidgetItem?

//Populate list 
QTreeWidgetItem *program = createCheckedTreeItem(QString::fromStdString(itr->first), true); 
treePrograms->addTopLevelItem(program); 

QTreeWidgetItem* ConfigDialog::createCheckedTreeItem(QString name,bool checkBoxState) 
{ 
    QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name)); 
    item->setFlags(item->flags()|Qt::ItemIsUserCheckable); 
    if (checkBoxState) 
    { 
    item->setCheckState(0,Qt::Unchecked); 
    } 
    else 
    { 
    item->setCheckState(0,Qt::Checked); 
    } 
    return item; 
} 

I necesita una manera de conectar una señal y ranura para cuando se cambia el estado de esta casilla de verificación. La forma actual en que lo he implementado es la siguiente, pero desafortunadamente no funciona. ¿Puede alguien explicar qué estoy haciendo mal y qué debo hacer para que se conecte?

connect(program, SIGNAL(toggled(bool)), this, SLOT(programChecked(bool))); 

Respuesta

4

Su QTreeWidgetItem está directamente relacionada con sus datos del modelo, por lo que debe conectarse a la señal del modelo de su QTreeWidget QAbstractItemModel::dataChanged ser notificado del cambio.

+3

Esto es incorrecto. QTreeWidget no tiene un modelo de usuario. –

+0

@GHuxley Pero aún puede conectarse al modelo predeterminado subyacente de QTreeWidget, p. Ej. 'treeWidget.model(). dataChanged.connect (handle_dataChanged)'. No estoy seguro de si esto es mejor que simplemente conectarme a 'itemChanged', pero parece similar. – blah238

6

Tienes que tomar la señal itemChanged (QTreeWidgetItem * item, int column) viniendo de QTreeWidget.

+1

Esto no es bueno porque se señalará constantemente ya que los datos del árbol también cambian. –

3

Conéctese a la señal itemClicked(QTreeWidgetItem* item, int column) del árbol. Al manejar la señal, simplemente verifique item->checkState(column).

+0

Cuando el usuario hace clic solo en la casilla de verificación, esto no se señalizará. Por ejemplo, el usuario hace clic en el elemento. Luego haga clic en la casilla de verificación. CheckState no se llamará en la casilla de verificación haga clic en. Esto es cierto al menos para Qt 5.3 – Chrismit

+0

Estoy usando bien en Qt 5.3.1 en este momento, tanto en Mac como en Win. –

+0

Esto funciona, pero debe verificar el estado comprobado del artículo con respecto a su propio modelo para ver los cambios. – kainjow

3

La mejor solución que encontramos fue que reimplementar setData en una subclase material:

void MyItem::setData(int column, int role, const QVariant& value) 
{ 
    const bool isCheckChange = column == 0 
     && role == Qt::CheckStateRole 
     && data(column, role).isValid() // Don't "change" during initialization 
     && checkState(0) != value; 
    QTreeWidgetItem::setData(column, role, value); 
    if (isCheckChange) { 
     MyTree *tree = static_cast<MyTree *>(treeWidget); 
     emit tree->itemCheckStateChanged(this, checkState(0) == Qt::Checked); 
    } 
} 

Realmente sería conveniente tener esto en Qt hecho, me hace pensar en una señal que contribuye itemCheckStateChanged allí directamente :)

PD: configuración Qt :: ItemIsUserCheckable no es necesario, este indicador está activado por defecto para todos los QTreeWidgetItems.

Cuestiones relacionadas