Qt literacy-QTableView theory summary

I. Overview

QTableView implements a tableview to display the elements in the model. This class is used to provide the standard tables previously provided by the QTable class, but this one uses a more flexible approach provided by Qt's model/view architecture.

The QTableView class is one of the Model/View classes and is part of Qt's Model/View framework.

QTableView implements the interface defined by the QAbstractItemView class to allow it to display data provided by models derived from the QAbstractItemModel class.
insert image description here
In general, it is more convenient and easier to view and modify data in the model/view way.

2. Navigation

We can navigate the cells in the table by clicking on a cell with the mouse, or by using the arrow keys. Because QTableView enables tabKeyNavigation by default, we can also press the Tab and Backtab keys to move between cells.

3. Visual appearance

The vertical header of the table can be obtained by the function verticalHeader(), and the horizontal header can be obtained by the function horizontalHeader(). You can use rowHeight() to get the height of each row in the table. Similarly, the width of a column can be obtained using columnWidth(). Since these two widgets are normal widgets, they can be hidden using their hide() function.

Rows and columns can be hidden and shown using hideRow() , hideColumn() , showRow() , and showColumn() . Columns can be selected using selectRow() and selectColumn(). The table will display a grid according to the showGrid property. Just after I set this to false. There are no grid lines.
insert image description here

Items displayed in a table view are rendered and edited just like items in other item views, using standard delegates.

We can also use the proxy method: use the following list to select the gender
insert image description here

However, for certain tasks it is sometimes useful to be able to insert other controls into the table.

Use the setIndexWidget() function to set the widget for a specific index, and then use indexWidget() to retrieve the widget.

By default, cells in a table do not expand to fill the available space.
You can make the cell fill the available space by stretching the last header section. Use horizontalHeader() or verticalHeader() to access the relevant headerview header object and set the header's stretchLastSection property.

To allocate available space according to the space requirements of each column or row, call the view's resizeColumnsToContents() or resizeRowsToContents() function. to achieve the following effect.

insert image description here

4. Coordinate system

For some special forms of tables it is useful to be able to convert between row and column indices and control coordinates.

The rowAt() function provides the y-coordinate of the view of the specified row; the row index can obtain the corresponding y-coordinate through rowViewportPosition().

The columnAt() and columnViewportPosition() functions provide equivalent conversion operations between x coordinates and column indices.

5. Example code

1. Gender proxy

// SexComboxDelegate.h
#ifndef SEXCOMBOXDELEGATE_H
#define SEXCOMBOXDELEGATE_H

#include <QObject>
#include <QStyledItemDelegate>
#include <QComboBox>

class SexComboxDelegate : public QStyledItemDelegate
{
    
    
    Q_OBJECT
public:
    SexComboxDelegate(QObject *parent = nullptr);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override;

    void setEditorData(QWidget *editor, const QModelIndex &index) const override;

    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override;

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const override;
};

#endif // SEXCOMBOXDELEGATE_H

// SexComboxDelegate.cpp
#include "SexComboxDelegate.h"

SexComboxDelegate::SexComboxDelegate(QObject *parent)
{
    
    

}

QWidget *SexComboxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    
    
    QComboBox *editor = new QComboBox(parent);

    editor->addItems(QStringList{
    
    "男", "女"});

    editor->setFrame(false);

    return editor;
}

void SexComboxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    
    
    QComboBox *combox = static_cast<QComboBox*>(editor);

    combox->setCurrentIndex(combox->findText(index.model()->data(index, Qt::DisplayRole).toString()));
}

void SexComboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    
    
    QComboBox *combox = static_cast<QComboBox*>(editor);

    model->setData(index, combox->currentText(), Qt::EditRole);
}

void SexComboxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    
    
    editor->setGeometry(option.rect);
}

2. Student Information Model

// StudentModel.h
#ifndef STUDENTMODEL_H
#define STUDENTMODEL_H

#include <QAbstractTableModel>
#include <QDebug>
#include <QColor>
#include <QBrush>
#include <QFont>

class StudentModel: public QAbstractTableModel
{
    
    
    Q_OBJECT
public:
    StudentModel(QObject *parent = nullptr);

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    QVariant headerData(int section, Qt::Orientation orientation, int role) const override;

    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;

    Qt::ItemFlags flags(const QModelIndex &index) const override;

    void setRow(int newRow);

    void setColumn(int newColumn);

    void setTableHeader(QList<QString> *header);

    void setTableData(QList<QList<QString>> *data);

signals:
    void editCompleted(const QString &);

public slots:
    void SlotUpdateTable();
private:
    int row = 0;
    int column = 0;

    QList<QString> *m_header;
    QList<QList<QString>> *m_data;
};

#endif // STUDENTMODEL_H

// StudentModel.cpp
#include "StudentModel.h"

StudentModel::StudentModel(QObject *parent) : QAbstractTableModel(parent)
{
    
    

}

int StudentModel::rowCount(const QModelIndex &parent) const
{
    
    
    return row;
}

int StudentModel::columnCount(const QModelIndex &parent) const
{
    
    
    return column;
}

QVariant StudentModel::data(const QModelIndex &index, int role) const
{
    
    
    if(role == Qt::DisplayRole || role == Qt::EditRole)
    {
    
    
        return (*m_data)[index.row()][index.column()];
    }

    if(role == Qt::TextAlignmentRole)
    {
    
    
        return Qt::AlignCenter;
    }

    if(role == Qt::BackgroundRole &&  index.row() % 2 == 0)
    {
    
    
        return QBrush(QColor(50, 50, 50));
    }

    return QVariant();
}

QVariant StudentModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    
    
    if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
    
    
        if(m_header->count() - 1 >= section)
            return m_header->at(section);
    }

    //qDebug()<<role << "--" << Qt::BackgroundRole;

//    if(role == Qt::BackgroundRole)
//    {
    
    
//        return QBrush(QColor(156, 233, 248));
//    }
//    if(role == Qt::ForegroundRole)
//    {
    
    
//         return QBrush(QColor(156, 233, 248));
//    }

    if(role == Qt::FontRole)
    {
    
    
         return QFont(tr("微软雅黑"),10, QFont::DemiBold);
    }
    return QVariant();
}

bool StudentModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    
    
    if (role == Qt::EditRole) {
    
    
         if (!checkIndex(index))
            return false;

         //save value from editor to member m_gridData
         (*m_data)[index.row()][index.column()] = value.toString();
         return true;
    }
    return false;
}

Qt::ItemFlags StudentModel::flags(const QModelIndex &index) const
{
    
    
    return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}

void StudentModel::setRow(int newRow)
{
    
    
    row = newRow;
}

void StudentModel::setColumn(int newColumn)
{
    
    
    column = newColumn;
}

void StudentModel::setTableHeader(QList<QString> *header)
{
    
    
    m_header = header;
}

void StudentModel::setTableData(QList<QList<QString> > *data)
{
    
    
    m_data = data;
}

void StudentModel::SlotUpdateTable()
{
    
    
    emit dataChanged(createIndex(0, 0), createIndex(row, column), {
    
    Qt::DisplayRole});
}

3. Corresponding view

// StudentWD.h
#ifndef STUDENTWD_H
#define STUDENTWD_H

#include <QWidget>
#include <Model/StudentModel.h>
#include <QFileDialog>
#include <QStandardPaths>
#include <QFile>
#include <QTextStream>
#include <Delegate/SpinBoxDelegate.h>
#include <Delegate/SexComboxDelegate.h>

namespace Ui {
    
    
class StudentWD;
}

class StudentWD : public QWidget
{
    
    
    Q_OBJECT

public:
    explicit StudentWD(QWidget *parent = nullptr);
    ~StudentWD();

private slots:
    void on_ImportBtn_clicked();

private:
    Ui::StudentWD *ui;

    StudentModel *model;
    SpinBoxDelegate *spinBoxDelegate;
    SexComboxDelegate *sexBoxDeleage;

    QList<QList<QString>> subject_table;
    QList<QString> subject_title;
};

#endif // STUDENTWD_H
// StudentWD.cpp
#include "StudentWD.h"
#include "ui_StudentWD.h"

StudentWD::StudentWD(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StudentWD),
    model(new StudentModel),
    spinBoxDelegate(new SpinBoxDelegate),
    sexBoxDeleage(new SexComboxDelegate)
{
    
    
    ui->setupUi(this);

    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

}

StudentWD::~StudentWD()
{
    
    
    delete ui;
}

void StudentWD::on_ImportBtn_clicked()
{
    
    
    QString fileName = QFileDialog::getOpenFileName(this,
                                            tr("打开 csv 文件"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), tr("Txt Files (*.txt *.csv *.*)"));

    subject_table.clear();
    subject_title.clear();

    if(!fileName.isNull() && !fileName.isEmpty())
    {
    
    
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
            return;

        int i = 0;
        QTextStream in(&file);
        in.setCodec("UTF-8");
        while (!file.atEnd()) {
    
    
            QString line = file.readLine();

            if(i == 0)
            {
    
    
                subject_title = line.split(",", QString::SkipEmptyParts);
                subject_title.last() = subject_title.last().trimmed();
                i++;
                continue;
            }
            subject_table.append(line.split(",", QString::SkipEmptyParts));
            subject_table.last().last() = subject_table.last().last().trimmed();
        }

        ui->Total_Subject_SB->setValue(subject_title.count());
        ui->Total_People_SB->setValue(subject_table.count());

        model->setColumn(subject_title.count());
        model->setRow(subject_table.count());

        model->setTableData(& subject_table);
        model->setTableHeader(& subject_title);

        ui->tableView->setModel(model);
        ui->tableView->setItemDelegateForColumn(0, spinBoxDelegate);
        ui->tableView->setShowGrid(true);

        ui->tableView->setItemDelegateForColumn(1, sexBoxDeleage);

        for (int i = 2; i < subject_table.count(); ++i) {
    
    
            ui->tableView->setItemDelegateForColumn(i, spinBoxDelegate);
        }
            ui->tableView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
    }

}

Corresponding ui file
insert image description here

Guess you like

Origin blog.csdn.net/qq_43680827/article/details/132299104