QTableView中的用户可编辑复选框

7

我希望在使用 QAbstractModel 创建的 QTableView 中实现一个用户可编辑的复选框。我能够分配一个已选中和未选中的复选框,但无法使其可编辑。 标志设置为 QItemIsUserCheckable


2
你在尝试做什么并不清楚。你能展示一下你的代码吗? - graphite
4个回答

15
您可以通过以下方式轻松实现模型的setData()方法:
bool yourModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid())
        return false;
    if (role == Qt::CheckStateRole)
    {
        if ((Qt::CheckState)value.toInt() == Qt::Checked)
        {
            //user has checked item
            return true;
        }
        else
        {
            //user has unchecked item
            return true;
        }
    }
    return false;
}

别忘了你的模型中的data()方法:

QVariant ProxyModelSubobjects::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    if (role == Qt::CheckStateRole && index.column() == COLUMN_WITH_CHECKBOX)
    {
        //return Qt::Checked or Qt::Unchecked here
    }
    //...
}

在第一个代码片段中,如果和否则有“返回true;”难道否则不应该返回false吗? 在第二个片段中,应该返回什么?返回Qt::Checked还是返回Qt::Unchecked? - Mubin Icyer

3
首先,如果你正在创建树形模型,则QAbstractItemModel是一个不错的选择。但在大多数情况下,使用QAbstractTableModel甚至QAbstractListModel更好,因为它们省去了为特定模型类型(表格或列表)实现虚拟方法的工作。
这些模型的文档非常详细,并告诉您为使模型可编辑而实现哪些函数。在本简短说明中,我将选择表格模型。主要函数有:
- QVariant data(index, role):返回当前索引和角色的QVariant值。 - bool setData(index, value, role):返回传递的值是否写入了索引。 - QItemFlags flags():返回传递索引的QItemFlags值。
对于此案例,我将忽略其他函数。
所有Qt视图的工作方式都相同 - 当它们显示时,它们会从模型中填充数据,其元素根据其索引的flags()方法返回的值进行编辑/选择等操作。当它们被编辑时,值会通过setData()函数传递到模型中。
您似乎缺少flags()方法中的Qt::ItemIsEditable标志。

1
在我查阅了一堆论坛并尝试了各种方法都无法解决问题后,最终在http://doc.qt.io/qt-4.8/modelview.html找到了一个注释。
在2.2节“使用角色扩展只读示例”的结尾处,文本注释:“现在我们需要确定如何使用分离的模型影响应用程序的性能,因此让我们跟踪视图调用data()方法的频率。为了跟踪视图调用模型的次数,我们在data()方法中放置了一个调试语句,该语句记录到错误输出流中。在我们的小例子中,data()将被调用42次。每当您将光标悬停在字段上时,data()将再次被调用——每个单元格7次。这就是为什么确保在调用data()时数据可用且昂贵的查找操作已缓存非常重要。”
这使我意识到“yourModal::data()”会不断被调用,然而,为了额外更新,我在设置中添加了一个时间来运行选择的检查。我的情况有点棘手,因为我实际上是从我的MainWindow打开一个groupBox弹出窗口,享受额外的代码。
所以基本上这是我想出来的代码,它运行得很好:
#ifndef ADD_PARAMETERS_GROUPBOX
#define ADD_PARAMETERS_GROUPBOX

#include <QGroupBox>
#include <QAbstractTableModel>

namespace Ui {
class AdditionalParameters;
}

class AdditionalParameters : public QGroupBox
{
    Q_OBJECT

public:

    explicit AdditionalParameters(QWidget *parent = 0);
    ~AdditionalParameters();

private:
    Ui::AdditionalParameters *ui;

signals:
    void stateChanged(int state);

private slots:
    void PARAMTER_SEL(QModelIndex box);
};

#endif // ADD_PARAMETERS_GROUPBOX

#ifndef ADD_PARAMETERS_SELECTION_TABLE
#define ADD_PARAMETERS_SELECTION_TABLE

#include <QAbstractTableModel>
#include <QString>
class MainWindow;

const int ROWS = 63;
const int COLS = 5;
class ParametersTable : public QAbstractTableModel
{
    Q_OBJECT
public:
    ParametersTable(QObject *parent);
    int rowCount(const QModelIndex &parent = QModelIndex()) const ;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    //bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::CheckStateRole);
    Qt::ItemFlags flags(const QModelIndex & index) const;

private:
     //QString m_gridData[ROWS][COLS];  //holds text entered into QTableView
     //bool m_gridData[ROWS][COLS];  //holds state entered into QTableView

signals:
    void editCompleted(const QString &);
    void stateChanged(int state);

private slots:
    //void updateTable();
    //void PARAMTER_SEL(QModelIndex box);
};




#include "add_parameters_groupbox.h"
#include "ui_add_parameters_groupbox.h"
#include "add_parameters_selection_table.h"


#include <QTableView>
#include <QAbstractTableModel>
#include <QList>
#include <QTimer>
#include <QDebug>
#include <qcheckbox.h>

QStringList paraHold;
QStringList paraSymbols;
QString Parameters[500][5];
QAbstractTableModel *paraTable;
QItemSelectionModel *selectionModel;

bool m_gridData[ROWS][COLS];

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

    paraTable = new ParametersTable(this);
    ui->AddPara_tableView->setModel(paraTable);

    connect(ui->AddPara_tableView,SIGNAL(clicked(QModelIndex)),
            this, SLOT(PARAMTER_SEL(QModelIndex)));

    paraHold 
             << "60 xxxx"
             << "lines"
             << "of strings";
    paraSymbols
             << "60+/-"
             << "lines"
             << "of strings";

    for(int i = 0; i<(paraHold.size()); i++)
    {
        Parameters[i][0] = paraHold.at(i);
        m_gridData[i][0] = false;
//        qDebug() << "m_gridData[i][0]:" << m_gridData[i][0];
        if((!Parameters[i][0].contains("T",Qt::CaseInsensitive))
                || (Parameters[i][0].contains("FET",Qt::CaseInsensitive))
                || (Parameters[i][0].contains("NT",Qt::CaseInsensitive))
                || (Parameters[i][0].contains("LT",Qt::CaseInsensitive))
                || (Parameters[i][0].contains("TAT",Qt::CaseInsensitive))){
        Parameters[i][1] = "Current/Voltage";
        m_gridData[i][1] = true;
//        qDebug() << "m_gridData[i][1]:" << m_gridData[i][1];
        }
        if(!((Parameters[i][0].contains("V",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("I_",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("cell",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("FET",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("NT",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("LT",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("_SCD",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("_CFA",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("_OWD",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("_CHG",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("_DSG",Qt::CaseInsensitive))
             || (Parameters[i][0].contains("OC",Qt::CaseInsensitive)))){
        Parameters[i][2] = "Tempurature";
        m_gridData[i][2] = true;
//        qDebug() << "m_gridData[i][2]:" << m_gridData[i][2];
        }
        Parameters[i][3] = paraSymbols.at(i);
    }
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), ui->AddPara_tableView, SLOT(doItemsLayout()));
//    connect(timer, SIGNAL(timeout()), ui->AddPara_tableView, SLOT(resizeColumnsToContents()));
//    QTimer::singleShot(20000, ui->AddPara_tableView, SLOT(doItemsLayout()));
    QTimer::singleShot(1000, ui->AddPara_tableView, SLOT(resizeColumnsToContents()));
    timer->start(1000);
}

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

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

}

int ParametersTable::rowCount(const QModelIndex & /*parent*/) const
{
    //int pararow = Parameters.size();
    //return pararow;
    return 62;
}

int ParametersTable::columnCount(const QModelIndex & /*parent*/) const
{
    //int paracol;
    return 5;
}

QVariant ParametersTable::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == Qt::DisplayRole)
    {
        if (orientation == Qt::Horizontal) {
            switch (section)
            {
            case 0:
                return QString("Parameter");
            case 1:
                return QString("Current/Voltage Chart");
            case 2:
                return QString("Tempurature Chart");
            case 3:
                return QString("Symbol");
            case 4:
                return QString("Color");
            }
        }
    }

    return QVariant();
}

QVariant ParametersTable::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    int col = index.column();

    switch(role){
    case Qt::DisplayRole:

        return QString("%1")
                .arg(Parameters[row][col]);

        break;
    case Qt::FontRole:
        if (Parameters[row][col] != "_")
        {
            QFont boldFont;
            boldFont.setBold(true);
            return boldFont;
        }

        break;
    case Qt::BackgroundRole:

        if(col == 4)
        {
            if (Parameters[row][0].contains("cell1",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::blue);
                return redBackground;
            }
            if (Parameters[row][0].contains("cell2",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::cyan);
                return redBackground;
            }
            if (Parameters[row][0].contains("cell3",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::magenta);
                return redBackground;
            }
            if (Parameters[row][0].contains("cell4",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::yellow);
                return redBackground;
            }
            if (Parameters[row][0].contains("cell5",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::darkGray);
                return redBackground;
            }
            if (Parameters[row][0].contains("cell6",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::red);
                return redBackground;
            }
            if (Parameters[row][0].contains("cell7",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::darkGreen);
                return redBackground;
            }

            if (Parameters[row][0].contains("I_",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::green);
                return redBackground;
            }
            if ((Parameters[row][0].contains("CH",Qt::CaseInsensitive))
                 || (Parameters[row][3].contains("+",Qt::CaseInsensitive)))
            {
                QBrush redBackground(Qt::green);
                return redBackground;
            }
            if ((Parameters[row][0].contains("DS",Qt::CaseInsensitive))
                    || (Parameters[row][3].contains("-",Qt::CaseInsensitive)))
            {
                QBrush redBackground(Qt::red);
                return redBackground;
            }
            if (Parameters[row][0].contains("V_Pack",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::darkRed);
                return redBackground;
            }

            if (Parameters[row][0].contains("T_ISL",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::darkMagenta);
                return redBackground;
            }
            if (Parameters[row][0].contains("T_HS",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::darkYellow);
                return redBackground;
            }
            if (Parameters[row][0].contains("T_LS",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::darkCyan);
                return redBackground;
            }
            if (Parameters[row][0].contains("T_B",Qt::CaseInsensitive))
            {
                QBrush redBackground(Qt::darkBlue);
                return redBackground;
            }

        }
        break;
    case Qt::TextAlignmentRole:

        if (col == 3) //change text alignment only for colum 3
        {
             return Qt::AlignCenter;//+ Qt::AlignVCenter;
        }
        break;
    case Qt::CheckStateRole:

        if((col == 0) && (m_gridData[row][0] == false)){  //add a checkbox to all rows in colum 0
//            qDebug() << "m_gridData[" << row << "][0]:" << m_gridData[row][0];
            return Qt::Unchecked;
        }
        else if((col == 0) && (m_gridData[row][0] == true)){
//            qDebug() << "m_gridData[" << row << "][0]:" << m_gridData[row][0];
            return Qt::Checked;
        }

        if((Parameters[row][1].contains("Current/Voltage",Qt::CaseSensitive)
            && (col == 1)) && (m_gridData[row][1] == true)){
//            qDebug() << "m_gridData[" << row << "][1]:" << m_gridData[row][1];
            return Qt::Checked;
        }
        else if((Parameters[row][1].contains("Current/Voltage",Qt::CaseSensitive) && (col == 1))
                && (m_gridData[row][1] == false)){
//            qDebug() << "m_gridData[" << row << "][1]:" << m_gridData[row][1];
            return Qt::Unchecked;
        }

        if(Parameters[row][2].contains("Tempurature",Qt::CaseSensitive)
                && (col == 2) && (m_gridData[row][2] == true)){
//            qDebug() << "m_gridData[" << row << "][2]:" << m_gridData[row][2];
            return Qt::Checked;
        }
        else if((Parameters[row][2].contains("Tempurature",Qt::CaseSensitive)
                 && (col == 2)) && (m_gridData[row][2] == false)){
//            qDebug() << "m_gridData[" << row << "][2]:" << m_gridData[row][2];
            return Qt::Unchecked;
        }
    }
    return QVariant();
}


Qt::ItemFlags ParametersTable::flags(const QModelIndex & /*index*/) const
{
    return Qt::ItemIsSelectable |  Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
}

void AdditionalParameters::PARAMTER_SEL(QModelIndex Box)
{
    int row = Box.row();
    int col = Box.column();

    if(!Parameters[row][col].isEmpty()){
        m_gridData[row][col] = (!(m_gridData[row][col]));
        qDebug() << "PARA_SEL @ m_gridData[row][col]:(" << row << "," << col << "):" << m_gridData[row][col];
    }
    emit stateChanged(m_gridData[row][col]);

}

1
你想要实现的是自定义委托。查看 QAbstractItemDelegate 类以获取有关实际实现的更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接