How to interact with checkbox actions ? (QTableVie

2019-02-19 00:53发布

问题:

I'm using QTableView and QStandardItemModel to show some data.

For each row, there is a column which has a check Box, this check box is inserted by setItem, the code is as follows:

int rowNum;
QStandardItemModel *tableModel;
QStandardItem* __tmpItem = new QStandardItem();

__tmpItem->setCheckable(true);
__tmpItem->setCheckState(Qt::Unchecked);

tableModel->setItem(rowNum,0,__tmpItem);

Now I want to interact with the check box. If a check box changes its state by user (from checked to unchecked or vice versa), I want to do something on the corresponding data row.

I know I can use signal-slot to catch the change of checkbox, but since there are lots of data row, I don't want to connect each row one by one.

Is there anyway to interact with the check action more effectively? Thanks :)

回答1:

handle the click event, there you will get the modelindex, get the data and modify the same

if you are going to insert more than one text or icon, then you need to set the delegate for your listview



回答2:

I don't deal with QTableView+QStandardItemModel, but may be example below will help you:

1). table.h file:

#ifndef TABLE__H
#define TABLE__H

#include <QtGui>

class ItemDelegate : public QItemDelegate
{
public:
    ItemDelegate(QObject *parent = 0)
        : QItemDelegate(parent)
    {
    }
    virtual void drawCheck(QPainter *painter, const QStyleOptionViewItem &option,
        const QRect &, Qt::CheckState state) const
    {
        const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;

        QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
            check(option, option.rect, Qt::Checked).size(),
            QRect(option.rect.x() + textMargin, option.rect.y(),
            option.rect.width() - (textMargin * 2), option.rect.height()));
        QItemDelegate::drawCheck(painter, option, checkRect, state);
    }
    virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
        const QModelIndex &index)
    {
        Q_ASSERT(event);
        Q_ASSERT(model);

        // make sure that the item is checkable
        Qt::ItemFlags flags = model->flags(index);
        if (!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled))
            return false;
        // make sure that we have a check state
        QVariant value = index.data(Qt::CheckStateRole);
        if (!value.isValid())
            return false;
        // make sure that we have the right event type
        if (event->type() == QEvent::MouseButtonRelease) {
            const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
            QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
                check(option, option.rect, Qt::Checked).size(),
                QRect(option.rect.x() + textMargin, option.rect.y(),
                option.rect.width() - (2 * textMargin), option.rect.height()));
            if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos()))
                return false;
        } else if (event->type() == QEvent::KeyPress) {
            if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
                && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
                return false;
        } else {
            return false;
        }
        Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
            ? Qt::Unchecked : Qt::Checked);

        QMessageBox::information(0,
            QString((state == Qt::Checked) ? "Qt::Checked" : "Qt::Unchecked"),
            QString("[%1/%2]").arg(index.row()).arg(index.column()));

        return model->setData(index, state, Qt::CheckStateRole);
    }
    virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
    {
        QItemDelegate::drawFocus(painter, option, option.rect);
    }
};


static int ROWS = 3;
static int COLS = 1;
class Table : public QTableWidget
{
    Q_OBJECT
public:
    Table(QWidget *parent = 0)
        : QTableWidget(ROWS, COLS, parent)
    {
        setItemDelegate(new ItemDelegate(this));
        QTableWidgetItem *item = 0;
        for (int i=0; i<rowCount(); ++i) {
            for (int j=0; j<columnCount(); ++j) {
                setItem(i, j, item = new QTableWidgetItem);
                item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);
                item->setCheckState((i+j) % 2 == 0 ? Qt::Checked : Qt::Unchecked);
            }
        }
    }
};

#endif

2). main.cpp file:

#include <QApplication>

#include "table.h"

int main(int argc, char **argv)
{
    QApplication a(argc, argv);
    Table w;
    w.show();
    return a.exec();
}

Good luck.

PS: here is the original text.



回答3:

Here is another similar idea of the example suggested by mosg using a QStyleItemDelegate instead. http://developer.qt.nokia.com/faq/answer/how_can_i_align_the_checkboxes_in_a_view