2011-12-07 18 views

Odpowiedz

13

Czy ustawiono stan sprawdzenia, a także czy można je kontrolować?

W moim przykładzie poniżej, ta linia jest krytyczna:

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

Jeżeli zostanie pominięty pola wyboru nie odda, ponieważ nie jest to prawidłowy stan zameldowania do renderowania.

Przykład pokazuje pola wyboru w combobox, liście i tabeli, ponieważ nie mogłem go uruchomić na początku, więc próbowałem różnych widoków.

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

Awesome - to na pewno działa! Teraz jeśli chcę podłączyć jeden z sygnałów z pola wyboru do gniazda (powiedzmy klikniętego(), aby zobaczyć, kiedy kliknięto i czy jest zaznaczone), w jaki sposób mógłbym to zrobić? QStandardItem nie pochodzi z QObject, więc nie może mieć sygnałów. Spojrzałem na sygnały dla QComboBox - sygnał highlighted() jest emitowany po najechaniu kursorem na nowe pole wyboru, ale nic nie wydaje się być emitowane, gdy kliknę pole wyboru? Próbowałem dodać Qt :: ItemIsSelectable do flag elementu, a następnie combobox :: currentIndexChanged jest emitowany, ale combobox zamyka się, co nie jest tym, czego chcę. –

+0

Będziesz musiał to zrobić w modelu, podklasę 'QAbstractListModel' i zaimplementować' rowCount', 'data',' flags' oraz 'setData'. Upewnij się, że model obsługuje rolę 'Qt :: CheckStateRole'. W 'setData' możesz strzelać sygnałami, ponieważ modele są pochodnymi QObject. –

+0

To jeszcze łatwiejsze niż to :). Bez żadnej podklasy konieczne: connect (this-> Model, SIGNAL (dataChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (slot_changed())); z: void MainWindow :: slot_changed() { std :: cout << "wyróżniony." << std :: endl; if (this-> Item-> checkState() == Qt :: Unchecked) { std :: cout << "Niezaznaczone!" << std :: endl; } else if (this-> Item-> checkState() == Qt :: Checked) { std :: cout << "Sprawdzono!" << std :: endl; } } –

10

Mam mały dodatek.

Jeśli ktoś skompiluje kod skyhisi to combobox na Mac OS X nie wygląda jak combobox z natywnymi polami wyboru. Możesz zobaczyć go na zrzucie .

enter image description here

Testowane qt 4.8.5 i 5.1.1.

Wygląda na to, że Qt samodzielnie rysuje te elementy sterujące. Nasz zespół ma znaleźć następujące obejście przez czysty wypadek.Można podklasy QStyledItemDelegate i reimplement paint() ten sposób:

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_); 
} 

Następnie można ustawić delegata do pola kombi, dodając następujące wiersze do skyhisi Kod:

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

combobox instalowane z tego delegata wygląd w następujący sposób: enter image description here

W systemie Windows może występować inny problem: tekst pola wyboru nakleił tło lub przerywaną ramkę wokół elementu:

enter image description here

Aby zmienić wygląd można dodać następującą linię do zastąpionej farby tylko przed linią QStyledItemDelegate :: Paint (painter_, refToNonConstOption, index_) (w próbce kodu linia ta była komentowana) :

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

Wynik:

enter image description here

+2

Cześć, ponieważ tam jest wybór wielokrotny w ComboBox (przykład Windows) to nie ma sensu, aby pokazać Tekst "Pozycja 0".Czy istnieje sposób, aby wyłączyć ten tekst lub zmienić go na coś w stylu "proszę, wybierz elementy" – Aleksandar

+0

@Aleksandar lub zamiast "Pozycja 0", która może * nie * została wybrana, powinniśmy zobaczyć "Pozycja1, Pozycja2": a konkatenacja wszystkich wybranych elementów w polu kombi. Czy ktoś wie, czy jest to wykonalne? –

+0

@ yvesBaumes Utworzyłem podklasę QComboBox, która aktualizuje widoczny tekst w zależności od wyboru (i kilku innych funkcji) https://gist.github.com/mistic100/c3b7f3eabc65309687153fe3e0a9a720 – Mistic

0

Można spróbować z 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

Starałem się uczynić ten przykład na Linux Mint, ale nie mogę zrobić pola wyboru widoczne. Musiałem wdrożyć klasę SubclassOfQStyledItemDelegate i ustawić delegata na pole wyboru, tak jak zalecał Neptilo i gshep.