QTableView(QAbstractTableModell)添加多选框

1,界面:

2,代码结构:

3,tablemodel.h

/* @brief 表模型类
 *
 * 通过继承QAbstractTableModel实现表格的MVC模型
 *
 * @author zhaoyong
 */


#ifndef TABLEMODEL_H
#define TABLEMODEL_H

#include <QAbstractTableModel>
#include <QTableView>
enum EN_USERROLE_TYPE
{
    EN_USERROLE_DATATYPE = 1,   //数据类型
    EN_USERROLE_COLUMNNAME = 2, //列名
    //    EN_USERROLE_SUBSYSTEM = 3,//所属应用
};

class TableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit TableModel( QObject* parent = nullptr );

    void setColumnTitle( const QStringList& listTitle );
    QStringList getColumnTitle();
    void setDelegateType( const QStringList& listDelegateType );

    void insertRow( const QStringList list );
    void removeRow( const int& row );
    void clear();

    QString getDelegateType( const int nColumn );

    const QList<QStringList>& getModelData();
    const QStringList& getModifyData();
    void clearModifyData();

    // Header:
    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;
    QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override;
    bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole );
    virtual Qt::ItemFlags flags( const QModelIndex& index ) const;

    // 更新表格数据
    void updateData(QList<QStringList> recordList);

public:
    QTableView* m_pTableView;

private:
    QStringList m_header;           //标题头
    QStringList m_dataType;         //数据类型
    QList<QStringList> m_data;      //数据内容,二维结构
    QStringList m_listModify;       //记录已修改的行和列,格式:row,col
};

#endif // TABLEMODEL_H

4,tablemodel.cpp

#include "tablemodel.h"
#include <QDebug>

#define CHECK_BOX_COLUMN 0

TableModel::TableModel( QObject* parent )
    : QAbstractTableModel( parent )
{
}

void TableModel::setColumnTitle( const QStringList& listTitle )
{
    m_header = listTitle;
}

QStringList TableModel::getColumnTitle()
{
    return m_header;
}

void TableModel::setDelegateType( const QStringList& listDelegateType )
{
    m_dataType = listDelegateType;
}

void TableModel::insertRow( const QStringList list )
{
//    if ( list.count() != m_header.count() )
//    {
//        return;
//    }
    beginResetModel();
    m_data.append( list );
    endResetModel();
}

void TableModel::removeRow( const int& row )
{
    beginResetModel();
    m_data.takeAt( row );
    endResetModel();
}

void TableModel::clear()
{
    beginResetModel();
    m_data.clear();
    endResetModel();
}

const QList<QStringList>& TableModel::getModelData()
{
    return m_data;
}

const QStringList& TableModel::getModifyData()
{
    return m_listModify;
}

void TableModel::clearModifyData()
{
    m_listModify.clear();
}

QString TableModel::getDelegateType( const int nColumn )
{
    if ( nColumn < 0 || nColumn >= m_dataType.count() )
        return "";

    return m_dataType.at( nColumn );
}

QVariant TableModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
    if ( Qt::DisplayRole == role && Qt::Horizontal == orientation && section < m_header.size() )
        return QVariant( m_header.at( section ) );
    else if ( Qt::DisplayRole == role && Qt::Vertical == orientation )
        return QVariant( section+1 );

    return QVariant();
}

int TableModel::rowCount( const QModelIndex& parent ) const
{
    if ( parent.isValid() )
        return 0;

    return m_data.count();
}

int TableModel::columnCount( const QModelIndex& parent ) const
{
    if ( parent.isValid() )
        return 0;

    return m_header.count();
}

// 表格项数据
QVariant TableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    int nRow = index.row();
    int nColumn = index.column();
    QStringList record = m_data.at(nRow);
    switch (role)
    {
    case Qt::TextColorRole:
        return QColor(Qt::black);
    case Qt::TextAlignmentRole:
        return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
    case Qt::DisplayRole:
    {
        if ( nRow <= m_data.count() )
            return m_data.at( index.row() ).at( index.column() );
    }
    case Qt::EditRole:
    {
        if ( nRow <= m_data.count() )
            return m_data.at( index.row() ).at( index.column() );
    }
    case Qt::UserRole + EN_USERROLE_DATATYPE:
    {
        if ( nRow <= m_data.count() )
            return m_dataType.at( index.column() );
    }
    case Qt::UserRole + EN_USERROLE_COLUMNNAME:
    {
        if ( nRow <= m_data.count() )
            return m_header.at( index.column() );
    }
    case Qt::CheckStateRole:
    {
        if (nColumn == CHECK_BOX_COLUMN)
        {
            if(record[CHECK_BOX_COLUMN] == true)
                return Qt::Checked;
            else return Qt::Unchecked;
        }
    }
    default:
        return QVariant();
    }
    return QVariant();
}

bool TableModel::setData( const QModelIndex& index, const QVariant& value, int role )
{
    if ( !index.isValid() )
        return false;
    int nColumn = index.column();
    QStringList record = m_data.at(index.row());
    if ( Qt::EditRole == role && index.row() <= m_data.count() &&
         m_data[index.row()][index.column()] != value.toString() )
    {
        m_data[index.row()][index.column()] = value.toString();
        QString sTmp = QString::number(index.row())+","+QString::number(index.column());
        if ( !m_listModify.contains(sTmp) )
            m_listModify.append( sTmp );
    }
    else if( Qt::CheckStateRole == role )
    {
        if (nColumn == CHECK_BOX_COLUMN)
        {
            record[CHECK_BOX_COLUMN] = (value.toInt() == Qt::Checked);
            m_data.replace(index.row(), record);
            emit dataChanged(index, index);
            return true;
        }
    }

    return true;
}


Qt::ItemFlags TableModel::flags( const QModelIndex& index ) const
{
    if ( !index.isValid() )
        return Qt::NoItemFlags;

    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    if (index.column() == CHECK_BOX_COLUMN)
    {
        flags |= Qt::ItemIsUserCheckable;
        return flags;
    }

    return QAbstractTableModel::flags( index ) | Qt::ItemIsEditable;
}

void TableModel::updateData( QList<QStringList> recordList )
{
    m_data = recordList;
    beginResetModel();
    endResetModel();
}

5,widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public slots:
    void slotCheckBoxChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight );
    void slotPrintSelectRows();

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
    QVector<int> selectRows;  //保存选择的行号
};

#endif // WIDGET_H

6,widget.cpp

 

#include "widget.h"
#include "ui_widget.h"
#include "tablemodel.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QTableView *pTableView = ui->tableView;
    TableModel *pModel = new TableModel(this);
    // 设置单行选中、最后一列拉伸、表头不高亮、无边框等
    pTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    pTableView->horizontalHeader()->setStretchLastSection(true);
    pTableView->horizontalHeader()->setHighlightSections(false);
    pTableView->verticalHeader()->setVisible(false);
    pTableView->setShowGrid(false);
    pTableView->setFrameShape(QFrame::NoFrame);
    pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
    pTableView->setModel(pModel);

    QStringList title;
    title << "select" << "bbb";
    pModel->setColumnTitle( title );
    // 加载数据、更新界面
    QList<QStringList> recordList;
    for (int i = 0; i < 5; ++i)
    {
        QStringList record;
        record << "";
        record << "adadfsdfsf";
        recordList.append(record);
    }
    pModel->updateData(recordList);
    connect( pModel, &TableModel::dataChanged, this, &Widget::slotCheckBoxChanged );
    connect( ui->pushButton, SIGNAL(clicked()), this, SLOT(slotPrintSelectRows() ) );
}

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

void Widget::slotCheckBoxChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight )
{
    int row = topLeft.row();
    if( selectRows.contains( row ) )
        selectRows.removeOne( row );
    else
        selectRows.append( row );
}

void Widget::slotPrintSelectRows()
{
    qDebug() << selectRows;
}

7,main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用 AbstractTableModel 构建Table 在表格中添加JButton按钮,之前在网上找了2天没有找到好用的程序,最终终于找到一个好用的例子。 不要使,我退你们分。。 sing the Swing JTable class can quickly become a sticky business when you want to customize it to your specific needs. First you must become familiar with how the JTable class is organized. Individual cells are rendered by TableCellRenderer implementations. The table contents are represented by an implementation of the TableModel interface. By default, JTable uses DefaultTableCellRenderer to draw its cells. DefaultTableCellRenderer recognizes a few primitive types, rendering them as strings, and can even display Boolean types as checkboxes. But it defaults to displaying the value returned by toString() for types it does not specifically handle. You have to provide your own TableCellRenderer implementation if you want to display buttons in a JTable. The TableCellRenderer interface contains only one method, getTableCellRendererComponent(...), which returns a java.awt.Component that knows how to draw the contents of a specific cell. Usually, getTableCellRendererComponent() will return the same component for every cell of a column, to avoid the unnecessary use of extra memory. But when the contents of a cell is itself a component, it is all right to return that component as the renderer. Therefore, the first step towards having JButtons display correctly in a JTable is to create a TableCellRenderer implementation that returns the JButton contained in the cell being rendered. In the accompanying code listing, JTableButtonRenderer demonstrates how to do this. Even after creating a custom TableCellRenderer, you're still not done. The TableModel associated with a given JTable does not only keep track of the contents of each cell, but it also keeps track of the class of data stored in each column. DefaultTableModel is designed to work with DefaultTableCellRenderer and will return java.lang.String.class for columns containing data types that it does not specifically handle. The exact method that does this is getColumnClass(int column). Your second step is to create a TableModel implementation that returns JButton.class for cells that contain JButtons. JTableButtonModel shows one way to do this. It just returns the result of getClass() for each piece of cell data. At this point, you're almost done, but not quite. What's the use of putting a JButton in a JTable if you can't press the darn thing? By default, JTable will not forward mouse events to components contained in its cells. If you want to be able to press the buttons you add to JTable, you have to create your own MouseListener that forwards events to the JButton cells. JTableButtonMouseListener demonstrates how you could do this.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值