Как сделать похожую таблицу в Qt?

171
11 ноября 2021, 08:20

Я новичок в Qt. Как сделать похожую таблицу в Qt?

Answer 1

Как пример, можно просто унаследовать свою модель от QAbstractTableModel.

testtablemodel.h:

#pragma once
#include <QAbstractTableModel>
#include <QPixmap>
class TestTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    struct TestData {
        QPixmap pixmap;
        QString name;
        QString desc;
        bool checked;
    };
    explicit TestTableModel(QObject *parent = nullptr);
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    Qt::ItemFlags flags(const QModelIndex& index) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    bool setData(const QModelIndex& index, const QVariant& value, int role) override;
    void initTestData();
private:
    QStringList headers;
    QList<TestData> rows;
};

testtablemodel.cpp:

#include "testtablemodel.h"
TestTableModel::TestTableModel(QObject *parent)
    : QAbstractTableModel(parent)
{
    headers << "Name" << "Description";
    initTestData();
}
QVariant TestTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section < headers.size()) {
        return headers.at(section);
    }
    return {};
}
int TestTableModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid()) return 0;
    return rows.size();
}
int TestTableModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid()) return 0;
    return headers.size();
}
QVariant TestTableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    auto row = rows.at(index.row());
    if(role == Qt::DisplayRole || role == Qt::EditRole ) {
        switch (index.column()) {
            case 0: return row.name;
            case 1: return row.desc;
        }
    }
    if(role == Qt::CheckStateRole && index.column() == 0 ) return row.checked;
    if(role == Qt::DecorationRole && index.column() == 0 ) return row.pixmap;
    return QVariant();
}
void TestTableModel::initTestData()
{
    for(int i=1;i<3;++i) {
        TestData td;
        td.name = QString("Name #%1").arg(i);
        td.desc = QString("Desc #%1").arg(i);
        td.checked = false;
        td.pixmap = QPixmap(QString(":/images/rsrc/%1.PNG").arg(i));
        rows.append(std::move(td));
    }
}
bool TestTableModel::setData(const QModelIndex& index, const QVariant&, int role)
{
    if(!index.isValid()) return false;
    if(role == Qt::CheckStateRole) {
        rows[index.row()].checked = (!rows[index.row()].checked);
    }
    return true;
}
Qt::ItemFlags TestTableModel::flags(const QModelIndex& index) const
{
    return QAbstractTableModel::flags(index) | Qt::ItemIsUserCheckable;
}

То есть достаточно переопределить Qt::DecorationRole и Qt::CheckStateRole для вывода картинки и комбобокса в первой колонке. Чтобы состояние комбобокса могло меняться необходимо добавить флаг, что Qt::ItemIsUserCheckable и соответствующую логику в setData.

После, модель можно просто добавить для таблицы, через setModel: auto model = new TestTableModel(this); auto table = ui->tableView;

table->setModel(model);
table->setSelectionBehavior(QAbstractItemView::SelectRows);
table->setSelectionMode(QTableView::ExtendedSelection);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
table->verticalHeader()->setVisible(false);
table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
table->verticalHeader()->setDefaultSectionSize(80);

Установка фона и цвета выделения, а также шрифтов и других параметров возможна через css-подобный синтаксис в setStyleSheet:

table->setStyleSheet("QTableView { "
                         "    font: 14px; "
                         "    background: #404142; "
                         "    border: 1px solid #282923; "
                         "} "
                         " "
                         "QTableView::item { "
                         "    background: transparent; "
                         "    color: white;"
                         "} "
                         " "
                         "QTableView::item:selected {  "
                         "  background: #FF9800;  "
                         "} ");

Если нужно сделать что-то сложнее, чем проста вставить картинку, то следует прочитать про делегаты в Qt.

READ ALSO
Передать string в функцию, когда требуется char

Передать string в функцию, когда требуется char

Подскажите, пожалуйста, как поступить в моей проблемеЕсть функция (библиотеки нестандартной), который в качестве аргумента требуется const char *

111
Как связать две структуры?

Как связать две структуры?

Сделал курсовую работуВозникла трудность с одним пунктом из технического задания, он звучит так:

281
static_cast&lt;int&gt;(abs(13200 / 1.1)) = 11999

static_cast<int>(abs(13200 / 1.1)) = 11999

Вопрос в том почему

76
Как из uint8 сделать QIcon?

Как из uint8 сделать QIcon?

У меня есть переменная типа uint8*, которая "заполнена" картинкойКак преобразовать её в QIcon? А вот функция, которая заполняет переменную типа...

195