我们必须将代码移植到 Qt6,其中出现问题的就是
QTableView
。
这绝对是一个改进 - 但我不知道如何修复隐藏在指示器下的文本重叠。唯一简单的选择也很糟糕:
QHeaderView::section:horizontal:first, QHeaderView::section:horizontal:only-one
进行格式化,我很难弄清楚后续列的格式)。这是一个超级简单的示例,显示了该行为,如果有人可以帮助我,直到 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();
}
我建议使用 Qt::DecorationRole 来显示图像,并且不使用 setStyleSheet。 我根据 Qt 模型帮助中的示例稍微修改了您的示例:
#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();
}