关于Qt的MVC模型model的headerData中设置BackgroundColorRole不生效的问题


说明

关于Qt的MVC模型视图框架本文就不多介绍了,本文仅记录一次自定义模型时遇到的问题。


一、问题描述

重写headerData函数,设置表头数据时,发现BackgroundColorRole设置背景色无效的问题,而其他的例如ForegroundRole,FontRole等都正常。部分主要代码如下:

void PositionDataForm::initui()
{
    m_delegate = new ItemDelegate(this);
    pSetModel();

    QList<QTableView*> pList;
    pList.append(ui->tableView_posnight);
    pList.append(ui->tableView_pos_dayshift);
    foreach (QTableView* view, pList) {
        view->setItemDelegate(m_delegate);       //为视图设置委托
        view->setDragEnabled(false);            //控件不允许拖动
//        view->setModel(mPositionModel);
        view->show();
        view->setShowGrid(false);
        view->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);//ResizeToContents自适应宽度,Stretch各列平均分配列宽
        view->verticalHeader()->setDefaultSectionSize(70);//设置默认行高
        view->horizontalHeader()->resizeSection(0,50); //设置表头第一列的宽度为150
        view->horizontalHeader()->setFixedHeight(50); //设置列表头的高度
        view->verticalHeader()->setFixedWidth(100); //设置行表头的宽度
        view->verticalHeader()->setVisible(false);
        view->setSelectionMode(QAbstractItemView::SingleSelection);//单选
        view->setEditTriggers(QAbstractItemView::NoEditTriggers);//禁止编辑

//        view->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
//        view->horizontalHeader()->setVisible(false);
//        view->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
//        view->setFrameShape(QFrame::NoFrame); //设置无边框
//        view->verticalHeader()->setVisible(false); //设置垂直头不可见
//        view->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
//        view->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
    }
    whiteDayModel = new PSortFilterProxyModel(0,12,2);
    nightModel = new PSortFilterProxyModel(12,24,2);

    whiteDayModel->setSourceModel(mPositionModel);
    nightModel->setSourceModel(mPositionModel);

    ui->tableView_pos_dayshift->setModel(whiteDayModel);
    ui->tableView_posnight->setModel(nightModel);
}
void PositionDataForm::pSetModel()
{
    mPositionModel = new QStandardItemModel(24,7);
    mPositionModel->setHorizontalHeaderLabels(TimeHorHeaderList);
    QStringList TimeLabelList;
    for(int i=0;i<24;i++){
        TimeLabelList.append(QString("%1:30-%2:30").arg(8+i>=24?8+i-24:8+i).arg(8+i+1>=24?8+i+1-24:8+i+1));
    }

    for(int r =0;r<24;r++)
    {
        QStandardItem *item = new QStandardItem();
        item->setData(TimeLabelList.at(r),Qt::UserRole);
        item->setData(QColor(0,0,0),Qt::ForegroundRole);
        item->setData(QColor(200,200,200),Qt::BackgroundRole);
        mPositionModel->setItem(r, 0, item);
    }

    for (int row =0; row < 24; ++row) {
        for (int column = 1; column < 7; ++column) {
            QStandardItem *item = new QStandardItem(QString("%1-%2").arg(row).arg(column));
            item->setData(QString("0(0%)"),Qt::UserRole);
            item->setData(QColor(0,0,0),Qt::ForegroundRole);
            item->setData(QColor(255,255,255),Qt::BackgroundRole);
            mPositionModel->setItem(row, column, item);
        }
    }
}

模型使用QStandardItemModel作为源模型,ItemDelegate自定义委托,继承自QStyledItemDelegate,用于自定义绘制。PSortFilterProxyModel从QSortFilterProxyModel派生,主要作用为区分时间段白夜班,类定义如下:

#include "psortfilterproxymodel.h"

PSortFilterProxyModel::PSortFilterProxyModel(quint8 start, quint8 end, quint8 goodcol, QObject *parent):
     QSortFilterProxyModel(parent),
     sRow(start),eRow(end),mgoodcol(goodcol)
{

}

bool PSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    if(sRow <= source_row && source_row<eRow){
        return true;
    }else{
        return false;
    }
    return QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
}
QVariant PSortFilterProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(Qt::Horizontal == orientation && role == Qt::ForegroundRole){
        return QVariant(QColor(0,0,255));
    }else if(Qt::Horizontal == orientation && role == Qt::BackgroundColorRole){//此处不生效
        if(section<mgoodcol) return QVariant(QColor(0,0,255));
        else if(section==mgoodcol) return QVariant(QColor(0,255,0));
        else return QVariant(QColor(255,0,0));
    }else if(Qt::Horizontal == orientation && role == Qt::FontRole){
        return QFont("微软雅黑", 15, QFont::Bold);
    }
    return QSortFilterProxyModel::headerData(section,orientation,role);
}


在这里插入图片描述
可以看到,字体及其颜色没毛病,但是背景设置无效,依然是白色!被这个问题困扰了三天,各种尝试,首先想到的肯定是直接设置样式tableview的setstylesheet,这个办法可以,但是没办法根据动态来调整不同列显示不同的背景色,因此放弃,继续寻找摸索。

百度了很久也没找到类似的帖子,只看到这个相同问题的:http://cn.voidcc.com/question/p-rtqtxfip-bdu.html

然后在Qt的bug反馈里面看到了一点有用的信息:https://bugreports.qt.io/browse/QTBUG-31804
据说好像是Qt的各平台风格的问题,QHeadView是通过绘制调色板来设置背景色,而有些风格样式不是基于调色板的,因此无效。
在这里插入图片描述到了这里,总算搞清楚了,但是怎么解决呢?于是乎,继续百度windows的风格样式相关的,终于找到了,链接如下:
https://www.gxlsystem.com/qianduan-344170.html

 QApplication::setStyle(QStyleFactory::create("fusion"));  

抱着试一试的心态,居然可以了,真特么的坑啊。。。

#include "mainwindow.h"

#include <QApplication>
#include <QStyleFactory>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qDebug()<< QStyleFactory::keys();//("Windows", "WindowsXP", "WindowsVista", "Fusion")
    QApplication::setStyle(QStyleFactory::create("Fusion"));
    MainWindow w;
    w.show();
    return a.exec();
}

//根据QT4文档的说明,windows下支持 "windows", "motif", "cde", "plastique" and "cleanlooks"

//而QT5文档说明,windows下只支持 "windows" and "fusion"

修改后运行如下:
在这里插入图片描述
虽然这个颜色看起来怪怪的,于是乎又尝试了windows的风格,如下:

QApplication::setStyle(QStyleFactory::create("Windows"));

效果:
在这里插入图片描述
好家伙,这才是255的蓝,由于字体也是255蓝,覆盖了,到了这里,问题也解决了。。。但还是不死心,于是有尝试了windowsxp和WindowsVista,发现无效,,合着不设置的话,那默认应该就是这两货之一。

另外,如果修改了全局的话,会影响其他控件,可以单独设置某个控件的风格,如下:

ui->tableView_pos_dayshift->setStyle(QStyleFactory::create("Fusion"));

这样也是可以的


总结

本文仅代表我个人方案,可能不适合所有人,如果你看到了这批文章或者你也遇到了类似的问题,并且有其他的解决方法或想法,欢迎留言讨论,共同进步。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt,可以通过`QApplication::setFont()`来设置应用程序的全局字体。如果在`MainWindow`设置了`qApp->setFont(font)`,但是字体并未生效,可能是以下原因之一: 1. 其他控件已经手动设置了字体,并覆盖了全局字体 如果在程序使用了某些控件,并在这些控件上手动设置了字体,那么这些控件的字体可能会覆盖全局字体,导致在应用程序设置的字体并未生效。 为了解决这个问题,你可以在需要修改字体的控件的槽函数,使用该控件的`setFont()`函数来单独设置控件的字体。例如: ``` QFont font("Microsoft YaHei"); font.setPointSize(12); ui->label->setFont(font); ``` 这个示例将字体设置为"Microsoft YaHei",大小为12个像素,并将其应用到名为"label"的控件上。你可以将"label"替换成你需要修改字体的控件的名称。 2. 字体文件未被正确加载 如果在应用程序设置的字体并未生效,那么可能是因为字体文件未被正确加载。在Qt,需要加载字体文件才能使用该字体。你可以通过`QFontDatabase::addApplicationFont()`函数来加载字体文件,例如: ``` int fontId = QFontDatabase::addApplicationFont(":/font/msyh.ttf"); QString fontFamily = QFontDatabase::applicationFontFamilies(fontId).at(0); QFont font(fontFamily); font.setPointSize(12); qApp->setFont(font); ``` 这个示例将一个名为"msyh.ttf"的字体文件加载到了应用程序,并将该字体应用到了整个应用程序。你需要修改代码的字体文件路径以匹配你的实际情况。 如果以上解决方法都无法解决你的问题,你可以提供更多的信息,例如你的代码和运行环境,这样可以更好地帮助我们找到问题的原因。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值