0

I am uploading QPixmap to QTableView via QSqlTableModel. On Linux, images are displayed in normal quality, but on Windows, the image quality is very low. Is it possible to fix it somehow?

Qt 6

fragment of my code:

SqlTableModel::SqlTableModel(QObject *parent, QSqlDatabase db)
    : QSqlTableModel(parent, db)
{
    int iconheight = QFontMetrics(QApplication::font()).height() * 2 - 4;
    m_IconSize = QSize(iconheight, iconheight);
    
    /*...*/
    
    m_ActoinMMIcon = QPixmap(":/resources/img/many_many.svg", "SVG").
            scaled(m_IconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);

   /*... etc ...*/
}

QVariant SqlTableModel::data(const QModelIndex &index, int role) const
{    
    if(role == Qt::BackgroundRole && isDirty(index)) return QBrush(QColor(Qt::yellow));

    auto field = record().field(index.column());
    auto tablename = field.tableName();
    auto fieldname = field.name();

    /*...*/
    
    // TABL_TASKS
    if(tablename == TABL_TASKS)
    {
        if(fieldname == COL_TASKACTTYPE)
        {
            if(role == Qt::DisplayRole) return QString();
            else if(role == Qt::DecorationRole)
            {
                auto value = QSqlTableModel::data(index, Qt::DisplayRole).toInt();
                if(value == Action::ManyFromMany) return m_ActoinMMIcon;
                else if(value == Action::OneFromMany) return m_ActoinOMIcon;
                else if(value == Action::AsValue) return m_ActoinValueIcon;
                else return m_ErrorIcon;
            }
            else if(role == Qt::SizeHintRole) return m_IconSize;
        }        
        /*...*/
    }
    
    /*...*/

    return QSqlTableModel::data(index, role);
}

Linux: Linux

Windows: Windows

avttrue
  • 387
  • 2
  • 12

2 Answers2

1

Before Qt 6 in the main() function before the app.exec() call we used to setting these:

// Unfortunately no longer working with Qt 6.
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling)
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

At least it did help with some problematic for Qt Windows graphics rendering hardware Integrated Intel® Graphics etc. given ANGLE support though not always a problem for Qt 5. With Qt 6 this may also due to ANGLE being removed from supporting graphics: How to ANGLE in Qt 6 OpenGL

Also using QML with ListView/etc for such case usually makes much better graphics experience. Widgets rendering depends on Qt's own graphics context.

One more consideration is proper sizing of icons or better use 1:1 source to viewport dimensions.

Alexander V
  • 8,351
  • 4
  • 38
  • 47
  • Thanks, I'll check it. Although, I use a Radeon. – avttrue Jan 24 '22 at 16:28
  • Both attributes are deprecated :) "High-DPI scaling is always enabled." "High-DPI pixmaps are always enabled." – avttrue Jan 24 '22 at 16:31
  • With SVG we should expect proper sizing but still some attributes may make the icon blurry. Then try to make complete match in pixels in between SVG original size and the view port. Say, 64x64 -> 64->64 and not 64x64->64x64 -> 45x45. It is not even always possible to scale right especially small icon. – Alexander V Jan 24 '22 at 16:41
  • It will be difficult to control it in this place. Interestingly, in all other cases: there is no such problem in QActions and other controls. – avttrue Jan 24 '22 at 16:47
  • At least you could try if that helps. – Alexander V Jan 24 '22 at 17:00
  • Thanks, I just need to find Windows again. Where do people get it? :) – avttrue Jan 24 '22 at 17:03
  • For us Windows is the best host to debug with VM with Linux. So we save the VM for many reasons to move it or investigate the bug or whatever. But still most corporate clients use Windows rather than Linux or Mac OS. – Alexander V Jan 24 '22 at 17:07
  • I fixed it. https://stackoverflow.com/a/70960003/12177714 – avttrue Feb 02 '22 at 17:22
1

Yes, I fixed it. The problem is detected if the interface scaling is enabled in the Windows 10 OS settings (in my case it is 125%). It wasn't immediately clear. The problem is fixed as follows:

SqlTableModel::SqlTableModel(QObject *parent, QSqlDatabase db)
    : QSqlTableModel(parent, db)
{
 auto pixelratio = qApp->primaryScreen()->devicePixelRatio();
 auto iconheight = config->GUISize();
 m_IconSize = QSize(iconheight, iconheight);
 
 /*...*/
 
 m_ActoinMMIcon = QPixmap(":/resources/img/many_many.svg", "SVG").
            scaled(m_IconSize * pixelratio, Qt::KeepAspectRatio, Qt::SmoothTransformation);
 m_ActoinMMIcon.setDevicePixelRatio(pixelratio);
 
 /*...*/
}
/* etc */
    
avttrue
  • 387
  • 2
  • 12
  • SVG scaling was not one to one and despite Scalable Vector Graphics we have quite poor SVG backend linked with GUI not always able to scale its icons properly. – Alexander V Feb 02 '22 at 22:40