Использование QStyledItemDelegate в QListView с QSqlQueryModel - PullRequest
10 голосов
/ 17 марта 2011

У меня есть QListView, в качестве модели которого задана QSqlQueryModel. Как я могу использовать QStyledItemDelegate для настройки внешнего вида строк QListView (например, показать 2 строки текста)?

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

По сути, я думаю, что мне нужно как-то «сопоставить» роли с полями таблицы БД, чтобы иметь возможность получать данные из QStyledItemDelegate, используя что-то вроде этого:

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));
    [...]
}

Спасибо!

1 Ответ

15 голосов
/ 18 марта 2011

Вы, конечно, можете использовать QStyledItemDelegate для пользовательского рисования элементов. QModelIndex имеет ссылку на объект модели, который вы можете использовать, чтобы получить поля записей «записей». Вам также нужно переопределить метод модели sizeHint , чтобы увеличить размер элементов, если вам нужно показать больше данных, чем отдельные данные. Кроме того, это более или менее тривиально.

Пожалуйста, посмотрите, подойдет ли вам приведенный ниже пример:

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

Набор тестовой базы данных определен здесь:

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

определение модели и списка:

initDb();

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

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

надеюсь, это поможет, с уважением

...