Checkbutton in Listview

Alles rund um die Programmierung mit Qt
Antworten
annica
Beiträge: 26
Registriert: 5. November 2010 10:01

Checkbutton in Listview

Beitrag von annica »

Hallo,

ich habe eine Listview, die ich mit Inhalt aus meiner DB fülle. Ich brauche allerdings jetzt noch Checkboxen an die einzelnen Einträge damit ich die Einträge auswählen kann, Wie kann man sowas denn machen? Bitte keine helft mir mit konkreten Beschreibungen, da ich in QT/C++ ein Neuling bin.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: Checkbutton in Listview

Beitrag von solarix »

Eine ListView? Dann hast du irgend ein "QAbstractItemModel".. in diesem Fall musst du also:

1. Zusätzlich flags() überladen und zu den Default-Flags auch noch "Qt::ItemIsUserCheckable" zurückliefern.
Dann weiss die ListView, dass du Checkboxen haben möchtest..

2. Bei der data()-Methode musst du weiter neben der DisplayRole auch noch die "Qt::CheckStateRole" beachten und was passendes zurückliefern (die zum Index gehörende Qt::CheckState)
Jetzt weiss die ListView, welchen Zustand die gerenderte CheckBox hat.

3. Bei der setData()-Methode musst du die "CheckStateRole" ebenfalls beachten (die neue CheckState im Model für die spätere Anwendung (u.a. für die data()-Methode) speichern).

IMHO wär's das..

hth
annica
Beiträge: 26
Registriert: 5. November 2010 10:01

Re: Checkbutton in Listview

Beitrag von annica »

Ersteinmal vielen Dank für deine Antwort.
Leider versteh ich nur die Hälfte. Sorry.

Ich nutze momentan eine QListView, diese verbinde ich mit der Methode auswahl_Element um zu prüfen welches angeklickt wurde, somit kann ich ja aber nur eins selectieren.

Code: Alles auswählen

connect(this->ui->listView_element,SIGNAL(clicked(const QModelIndex &)),this,SLOT(auswahl_Element(const QModelIndex &)));
Was soll denn dann in der flags() methode drin stehen? Für was und an welcher stelle muss ich das überschreiben?
Auch bei Punkt zwei und drei weiß ich nicht was zu tun ist.
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: Checkbutton in Listview

Beitrag von archer »

Du solltest Dir mal das Thema Model/View Programming in der Dokumentation ansehen.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Checkbutton in Listview

Beitrag von franzf »

QListView zeigt Daten an, die ein Model liefert. Dieses model hast du irgendwo per setModel() der view zugewiesen. Und genau dieses Model muss such auf die von solarix beschriebene Weise um Checkbarkeit und CheckState kümmern. Seine Punkte sind demnach im Model umzusetzen.
Was für ein Model verwendest du denn?
annica
Beiträge: 26
Registriert: 5. November 2010 10:01

Re: Checkbutton in Listview

Beitrag von annica »

Ich benutze QStringListModels
annica
Beiträge: 26
Registriert: 5. November 2010 10:01

Re: Checkbutton in Listview

Beitrag von annica »

Ich habe jetzt folgendes versucht:
Ich habe mir eine eigene Modelklasse gebastelt --> MyListModel

MyListModel.h

Code: Alles auswählen

#ifndef MYLISTMODEL_H
#define MYLISTMODEL_H
#include <QAbstractListModel>

class MyListModel
{
Q_OBJECT
public:
    MyListModel(QObject *parent);
    int rowCount(const QModelIndex &parent = QModelIndex()) const ;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
};

#endif // MYLISTMODEL_H
MyListModel.cpp

Code: Alles auswählen

#include "mylistmodel.h"
#include <QAbstractListModel>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>
#include <QDebug>
MyListModel::MyListModel(QObject *parent)
    :QAbstractListModel(parent)
{

}

int MyListModel::rowCount(const QModelIndex & /*parent */) const
{
    return 10;
}

QVariant MyListModel::data(const QModelIndex &index, int role) const
{
    switch(role){
        case Qt::DisplayRole:
            return index.row().toString();
            break;
        case Qt::FontRole:

            break;
        case Qt::BackgroundRole:

            break;
        case Qt::TextAlignmentRole:
            return Qt::AlignLeft;
            break;
        case Qt::CheckStateRole:
            return Qt::Unchecked;
    }
    return QVariant();
}
jetzt bekomme ich aber die fehlermeldung: In constructor 'MyListModdel::MyListModel(QObject*)': type QAbstractListModel is not a direct base of MyListModel

Was ist denn da falsch?
annica
Beiträge: 26
Registriert: 5. November 2010 10:01

Re: Checkbutton in Listview

Beitrag von annica »

Ok ich habs gefunden --> im Header fehlte:

Code: Alles auswählen

class MyListModel: public QAbstractListModel
annica
Beiträge: 26
Registriert: 5. November 2010 10:01

Re: Checkbutton in Listview

Beitrag von annica »

So jetzt bin ich schon etwas weiter glaub ich

ich habe jetzt die Flags Methode, die Data Methode und die SetData Methode so überschrieben:

Code: Alles auswählen

QVariant MyListModel::data(const QModelIndex &index, int role) const
{
    switch(role){
        case Qt::DisplayRole:
            return QString("%1").arg(this->stringList.at(index.row()));
            break;
        case Qt::TextAlignmentRole:
            return Qt::AlignLeft;
            break;
        case Qt::CheckStateRole:
            return Qt::Unchecked;
    }
    return QVariant();
}

Qt::ItemFlags MyListModel::flags(const QModelIndex &index) const
 {
     if (!index.isValid()){
         return Qt::ItemIsEnabled;
     }
     return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
 }
bool MyListModel::setData(const QModelIndex &index,const QVariant &value, int role){
    if(index.isValid() && role == Qt::CheckStateRole){
        qDebug()<<"etwas verändert";
        return true;
    }
     return false;
 }
Frage ist das erstmal so correct? Wenn nein, wie muss es dann? Und wie kann ich dann jetzt die Box auf checked setzen? Ich denke mal man muss das QVariant verändern, aber ich weiß nicht wie.
Bitte helft mir so kurz vorm Ziel
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: Checkbutton in Listview

Beitrag von solarix »

Naja.. eine gute Idee wäre es, den CheckState nicht hardcodiert zurückzugeben, sondern halt aus einem Zwischenpuffer:

Code: Alles auswählen

QVariant MyListModel::data(const QModelIndex &index, int role) const
{
    switch(role){
        case Qt::DisplayRole:
            return this->stringList.at(index.row());
          ...
        case Qt::CheckStateRole:
            return this->checkStateList.at(index.row()));
    }
Auf den Rest (mit der setData()-Methode) wirst du jetzt noch kommen.. oder? :wink:
annica
Beiträge: 26
Registriert: 5. November 2010 10:01

Re: Checkbutton in Listview

Beitrag von annica »

nee da passiert nichts :(

hier nochmal mein code:

Code: Alles auswählen

bool MyListModel::setData(const QModelIndex &index,const QVariant &value, int role){
     if(index.isValid() && role == Qt::CheckStateRole){
        if(this->stateList.at(index.row())){
            this->stateList[index.row()] = false;
            return true;
        }
        else{
            this->stateList[index.row()] = true;
                return true;
        }
    }else{
        return false;
    }
 }

archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: Checkbutton in Listview

Beitrag von archer »

Deine flags() Methode ist zum Editieren unvollständig, probiers damit:

Code: Alles auswählen

Qt::ItemFlags MyListModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags Flags = QAbstractItemModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsUserCheckable;
}
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: Checkbutton in Listview

Beitrag von archer »

Noch ein Tip, in value ist der Zustand der CheckBox enthalten:

Code: Alles auswählen

bool MyListModel::setData(const QModelIndex &index,const QVariant &value, int role)
{
    if (index.isValid() && role == Qt::CheckStateRole)
    {
        if (value.toInt() == Qt::Checked)    
            stateList[index.row()] =  true;
        else
            stateList[index.row()] =  false;

        return true;
    }
    else
    {
        return false;
    }
}
Antworten