2011-12-07 13 views

risposta

13

Hai impostato uno stato di controllo e li hai controllati?

Nel mio esempio qui sotto, questa linea è fondamentale:

item->setData(Qt::Unchecked, Qt::CheckStateRole); 

Se omesso le caselle di controllo non renderà come non c'è un check-stato valido per il rendering.

L'esempio mostra le caselle di controllo in una casella combinata, elenco e tabella, in quanto non è stato possibile farlo funzionare inizialmente, quindi ho provato diverse visualizzazioni.

test.cpp

#include <QtGui> 

int main(int argc, char** argv) 
{ 
    QApplication app(argc, argv); 

    QStandardItemModel model(3, 1); // 3 rows, 1 col 
    for (int r = 0; r < 3; ++r) 
    { 
     QStandardItem* item = new QStandardItem(QString("Item %0").arg(r)); 

     item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); 
     item->setData(Qt::Unchecked, Qt::CheckStateRole); 

     model.setItem(r, 0, item); 
    } 

    QComboBox* combo = new QComboBox(); 
    combo->setModel(&model); 

    QListView* list = new QListView(); 
    list->setModel(&model); 

    QTableView* table = new QTableView(); 
    table->setModel(&model); 

    QWidget container; 
    QVBoxLayout* containerLayout = new QVBoxLayout(); 
    container.setLayout(containerLayout); 
    containerLayout->addWidget(combo); 
    containerLayout->addWidget(list); 
    containerLayout->addWidget(table); 

    container.show(); 

    return app.exec(); 
} 

test.pro

QT=core gui 
SOURCES=test.cpp 
+1

Impressionante: questo sicuramente fa il trucco! Ora se voglio connettere uno dei segnali del checkbox a uno slot (per esempio, cliccato su(), per vedere quando è stato cliccato e se è stato selezionato), come lo farei? QStandardItem non è derivato da QObject, quindi non può avere segnali. Ho guardato i segnali per QComboBox - il segnale evidenziato() viene emesso quando passa il mouse su una nuova casella di controllo, ma nulla sembra essere emesso quando faccio clic sulla casella di controllo? Ho provato ad aggiungere Qt :: ItemIsSelectable ai flag dell'elemento, quindi viene emesso combobox :: currentIndexChanged, ma la combobox si chiude, che non è quello che voglio.Ideas? –

+0

Dovrai farlo nel modello, sottoclasse 'QAbstractListModel' e implementare' rowCount', 'data',' flags' e 'setData'. Assicurati che il modello gestisca il ruolo 'Qt :: CheckStateRole'. In 'setData' puoi attivare i tuoi segnali quando i modelli sono derivati ​​da QObject. –

+0

È ancora più semplice :). Senza alcuna sottoclasse necessaria: connect (this-> Model, SIGNAL (dataChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (slot_changed())); con: void MainWindow :: slot_changed() { std :: cout << "evidenziato". << std :: endl; if (this-> Item-> checkState() == Qt :: Unchecked) { std :: cout << "Deselezionato!" << std :: endl; } else if (this-> Item-> checkState() == Qt :: Checked) { std :: cout << "Selezionato!" << std :: endl; }} –

10

Ho una piccola aggiunta.

Se si compila il codice skyhisi, la casella combinata su Mac OS X non ha l'aspetto di una casella combinata con caselle di controllo native. Puoi vederlo sullo screenshot.

enter image description here

testato con qt-4.8.5 e 5.1.1.

Sembra che Qt disegna questi controlli da solo. Il nostro team ha trovato la seguente soluzione per puro caso.È possibile creare una sottoclasse QStyledItemDelegate e reimplementare paint() in questo modo:

void SubclassOfQStyledItemDelegate::paint(QPainter * painter_, const QStyleOptionViewItem & option_, const QModelIndex & index_) const 
{ 
    QStyleOptionViewItem & refToNonConstOption = const_cast<QStyleOptionViewItem &>(option_); 
    refToNonConstOption.showDecorationSelected = false; 
    //refToNonConstOption.state &= ~QStyle::State_HasFocus & ~QStyle::State_MouseOver; 

    QStyledItemDelegate::paint(painter_, refToNonConstOption, index_); 
} 

È quindi possibile impostare questo delegato alla casella combinata aggiungendo le seguenti righe al skyhisi di codice:

SubclassOfQStyledItemDelegate *delegate = new SubclassOfQStyledItemDelegate(this); 
combo->setItemDelegate(delegate); 

La comboBox installato con questo delegato sguardi il seguente modo: enter image description here

Su Windows può esserci un altro problema: il testo dei checkBox ha sfondo attaccato o tratteggiato attorno a un articolo:

enter image description here

Per cambiare questo aspetto si può aggiungere la seguente riga alla vernice override solo prima della linea QStyledItemDelegate :: vernice (painter_, refToNonConstOption, index_) (nel codice di esempio questa linea è stata commentata) :

refToNonConstOption.state &= ~QStyle::State_HasFocus & ~QStyle::State_MouseOver; 

Risultato:

enter image description here

+2

Ciao, poiché non v'è la selezione multipla in comboBox (finestre esempio) che non ha senso per mostrare "Articolo 0" testo.C'è un modo per disabilitare quel testo o per cambiarlo in qualcosa come "per favore, selezionare gli articoli" – Aleksandar

+0

@Aleksandar o invece di "Articolo 0" che potrebbe * non * essere stato selezionato, dovremmo vedere "Elemento1, Elemento2": a concatenazione di tutti gli elementi selezionati nella casella combinata. Qualcuno sa se è fattibile? –

+0

@yvesBaumes Ho creato una sottoclasse un QComboBox che aggiorna il testo visibile in base alla selezione (e ad alcune altre funzionalità) https://gist.github.com/mistic100/c3b7f3eabc65309687153fe3e0a9a720 – Mistic

0

Si può provare questo con QListView:

QStringList values = QStringList << "check 1" << "check 2" << "check 3" << "check 4"; 

QStandardItemModel model = new QStandardItemModel; 
for (int i = 0; i < values.count(); i++) 
{ 
    QStandardItem *item = new QStandardItem(); 
    item->setText(values[i]); 
    item->setCheckable(true); 
    item->setCheckState(Qt::Unchecked); 
    model->setItem(i, item); 
} 

ui->list->setModel(model); 
0

Ho provato a fare questo esempio su Linux Mint, ma non posso fare le caselle di controllo visibile. Ho dovuto implementare la classe SubclassOfQStyledItemDelegate e impostare il delegato sulla casella di controllo come Neptilo e gshep consigliato.