Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
704 views
in Technique[技术] by (71.8m points)

qt - Using a QStyledItemDelegate on a QListView with QSqlQueryModel

I have a QListView, that has a QSqlQueryModel set as its model. How can I use a QStyledItemDelegate in order to customise the QListView's rows' appearence (e.g. show 2 text lines) ?

QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE" );
db.setDatabaseName( "test.db" );
if( !db.open() )
{
    qDebug() << db.lastError();
    qFatal( "Failed to connect." );
}

qDebug( "Connected!" );

QSqlQueryModel *sqlModel = new QSqlQueryModel;
sqlModel->setQuery("SELECT * FROM entries");

mListWidget->setModel(sqlModel);

Essentially, what I think I need to do is to somehow "match" roles to db table's fields, in order to be able to get the data from the QStyledItemDelegate, using something like this:

void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    [...]
    QString headerText = qvariant_cast<QString>(index.data(headerRole));
    QString subText = qvariant_cast<QString>(index.data(subHeaderRole));
    [...]
}

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You certainly can use QStyledItemDelegate for custom item drawing. QModelIndex has a reference to the model object which you can use to get "entries" record fields. You also have to redefine model's sizeHint method to increase items size if you need to show more data then a single data. Other then that it's more or less trivial.

Pls, see if an example below would work you:

class ListViewDelegate : public QStyledItemDelegate
{
protected:
    void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
    {
        QStyleOptionViewItemV4 opt = option;
        initStyleOption(&opt, index);

        QString line0 = index.model()->data(index.model()->index(index.row(), 1)).toString();
        QString line1 = index.model()->data(index.model()->index(index.row(), 2)).toString();

        // draw correct background
        opt.text = "";
        QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
        style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);

        QRect rect = opt.rect;
        QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
        if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
            cg = QPalette::Inactive;

        // set pen color
        if (opt.state & QStyle::State_Selected)
            painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
        else
            painter->setPen(opt.palette.color(cg, QPalette::Text));

        // draw 2 lines of text
        painter->drawText(QRect(rect.left(), rect.top(), rect.width(), rect.height()/2),
                          opt.displayAlignment, line0);
        painter->drawText(QRect(rect.left(), rect.top()+rect.height()/2, rect.width(), rect.height()/2),
                          opt.displayAlignment, line1);
    }

    QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const
    {
        QSize result = QStyledItemDelegate::sizeHint(option, index);
        result.setHeight(result.height()*2);
        return result;
    }
};

The test database set is defined here:

QSqlError initDb()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");

    if (!db.open())
        return db.lastError();

    QStringList tables = db.tables();
    if (tables.contains("test", Qt::CaseInsensitive))
        return QSqlError();

    QSqlQuery q;
    if (!q.exec(QLatin1String("create table entries(id integer primary key, first_line varchar, second_line varchar)")))
        return q.lastError();

    q.exec("insert into entries(id, first_line, second_line) values(0, 'first line 0', 'second line 0')");
    q.exec("insert into entries(id, first_line, second_line) values(1, 'first line 1', 'second line 1')");
    q.exec("insert into entries(id, first_line, second_line) values(2, 'first line 2', 'second line 2')");

    return QSqlError();
}

model and listview definition:

initDb();

QSqlQueryModel *sqlModel = new QSqlQueryModel();
sqlModel->setQuery("SELECT * FROM entries");

ui->listView->setModel(sqlModel);
ui->listView->setItemDelegate(new ListViewDelegate());

hope this helps, regards


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...