带样式表的 QTableView - 指示器与 Qt6 中的文本重叠

问题描述 投票:0回答:1

我们必须将代码移植到 Qt6,其中出现问题的就是

QTableView

  • 在 Qt 5,15 及更早版本中,应用带有自定义复选框指示器的样式表效果很好。
  • 在 Qt 6.5.3 中,自定义图像指示器重叠在默认复选框和项目文本上。
  • 在 Qt 6.6.3 和 6.7.2 中,自定义图像指示器显示良好,默认指示器不再显示,但指示器仍然与文本重叠。

version comparison

这绝对是一个改进 - 但我不知道如何修复隐藏在指示器下的文本重叠。唯一简单的选择也很糟糕:

  • 添加大量空格(文本换行仍会受到影响)。
  • 将复选框作为单独的列插入(我尝试过,但标题使用
    QHeaderView::section:horizontal:first, QHeaderView::section:horizontal:only-one
    进行格式化,我很难弄清楚后续列的格式)。
  • 我尝试比较 Qt 版本,但我不明白这些更改来自哪里。

这是一个超级简单的示例,显示了该行为,如果有人可以帮助我,直到 Qt 完全修复它。它的行为与真实程序相同,图像覆盖文本。

main.cpp:

#include "mymodel.h"
#include <QApplication>
#include <QTableView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTableView tableView;
    MyModel myModel;
    tableView.setModel(&myModel);

    QString viewStyle = "QTableView::item { padding: 10px; }\n"
                        "QTableView::indicator { width: 30px; height: 30px; }\n"
                        "QTableView::indicator:unchecked { image: url(:/checkbox_unselected.png); }\n"
                        "QTableView::indicator:checked { image: url(:/checkbox_selected.png); } ";
    tableView.setStyleSheet(viewStyle);
    tableView.setColumnWidth(0, 100);
    tableView.setColumnWidth(1, 100);
    tableView.setColumnWidth(2, 100);
    tableView.setRowHeight(0, 100);
    tableView.setRowHeight(1, 100);

    tableView.show();
    return a.exec();
}

mymodel.h

#include <QAbstractTableModel>

class MyModel : public QAbstractTableModel
{
public:
    explicit MyModel(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;
};

我的模型.cpp

#include "mymodel.h"

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

int MyModel::rowCount(const QModelIndex & /*parent*/) const
{
    return 2;
}

int MyModel::columnCount(const QModelIndex & /*parent*/) const
{
    return 3;
}

QVariant MyModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole) {
        return QString("Row%1, Column%2").arg(index.row() + 1).arg(index.column() +1);
    }
    else if (role == Qt::CheckStateRole) {
        return (index.column() == 0) ? Qt::Checked : Qt::Unchecked;
    }
    return QVariant();
}
c++ qt tableview stylesheet
1个回答
0
投票

我建议使用 Qt::DecorationRole 来显示图像,并且不使用 setStyleSheet。 我根据 Qt 模型帮助中的示例稍微修改了您的示例:

enter image description here

#include <QApplication>
#include <QTableView>
#include <QStandardItemModel>
#include <QStyle>

class MyModel : public QStandardItemModel
{
private:
    QPixmap checkedPix, uncheckedPix;
    const int f=22;
public:
    explicit MyModel(QObject *parent = nullptr):QStandardItemModel(parent){
        checkedPix=qApp->style()->standardPixmap(QStyle::SP_DialogApplyButton).scaled(f,f, Qt::KeepAspectRatio);
        uncheckedPix=qApp->style()->standardPixmap(QStyle::SP_DialogCancelButton).scaled(f,f, Qt::KeepAspectRatio);
    }

    QVariant data(const QModelIndex &index, int role) const override
    {
        if(!index.isValid())
            return {};
        // Qt::DecorationRole
        if(role==Qt::DecorationRole){
            if(item(index.row(), index.column())->checkState()==Qt::Checked)
                return QVariant(checkedPix);
            else
                return QVariant(uncheckedPix);
        }
        else if(role==Qt::DisplayRole){
            return QVariant(item(index.row(), index.column())->text());
        }
        /*
        If you remove this "else if", the checkbox will not be 
        shown in the table cell, and its state can only be 
        controlled programmatically.
        */
        else if (role == Qt::CheckStateRole) {
            return item(index.row(), index.column())->checkState();
        }
        return {};
    }


    int rowCount(const QModelIndex & parent=QModelIndex()) const override
    {
        return 5;
    }


    int columnCount(const QModelIndex & parent=QModelIndex()) const override
    {
        return 1;
    }


    QVariant headerData(int section, Qt::Orientation orientation,
                                         int role) const override
    {
        if (role != Qt::DisplayRole)
            return {};

        if (orientation == Qt::Horizontal)
            return QStringLiteral("Column %1").arg(section+1);
        else
            return QStringLiteral("%1").arg(section+1);
    }


    Qt::ItemFlags flags(const QModelIndex &index) const
    {
        if (!index.isValid())
            return Qt::ItemIsEnabled;
        return QAbstractItemModel::flags(index) | (Qt::ItemIsEditable | Qt::ItemIsUserCheckable);
    }


    bool setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if (index.isValid() && role == Qt::EditRole) {
            item(index.row(), index.column())->setText(value.toString());
            emit dataChanged(index, index, {role});
            return true;
        }
        else if(index.isValid() && role == Qt::CheckStateRole){
            Qt::CheckState st= (value.toInt()==0 ? Qt::Unchecked : Qt::Checked);

            item(index.row(), index.column())->setCheckState(st);
            emit dataChanged(index, index, {role});
            return true;
        }
        return false;
    }
};




int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTableView tableView;
    MyModel myModel;
    tableView.setModel(&myModel);

    for(int row=0; row<myModel.rowCount(); row++){
        auto item=new QStandardItem("item");
        item->setCheckState(row%2==0 ? Qt::Checked : Qt::Unchecked);
        myModel.setItem(row, 0, item);
    }

    tableView.show();
    return a.exec();
}
© www.soinside.com 2019 - 2024. All rights reserved.