Merge pull request #2741

Workaround for WindowsVista style (qwindowsvistastyle plugin)

There is some strange bug on windows with the system styles (windows
and windowsvista).  When styleproxy is used and QDockWidget has a
custom stylesheet applied to the widget title, close-button and
float-button are rendered huge.

See #2485
This commit is contained in:
mgrojo
2021-06-18 23:11:13 +02:00
3 changed files with 72 additions and 35 deletions
+59 -5
View File
@@ -7,6 +7,10 @@
#include <QDebug>
#include <QAction>
#include <QFileInfo>
#include <QProxyStyle>
#include <QStyleOption>
#include <QDesktopWidget>
#include <QScreen>
#include "Application.h"
#include "MainWindow.h"
@@ -15,6 +19,52 @@
#include "version.h"
#include "sqlitedb.h"
class DB4SProxyStyle final : public QProxyStyle {
public:
DB4SProxyStyle(int toolBarIconSize, qreal dpi, QStyle *style)
: QProxyStyle(style), m_toolBarIconSize(static_cast<int>(toolBarIconSize * dpi / 96))
{
#ifdef Q_OS_WIN
m_smallIconSize = static_cast<int>(11 * dpi / 96);
QStyleOption so(QStyleOption::Version, QStyleOption::SO_MenuItem);
m_menuItemIconSize = style->pixelMetric(PM_SmallIconSize, &so);
#endif
}
int pixelMetric(QStyle::PixelMetric metric,
const QStyleOption *option = nullptr,
const QWidget *widget = nullptr) const override
{
if (metric == PM_ToolBarIconSize) {
return m_toolBarIconSize;
}
#ifdef Q_OS_WIN
else if (metric == PM_SmallIconSize) {
// set maximum icon size for SmallIcon
// Set default MenuIcon size
if (option && option->type == QStyleOption::SO_MenuItem) {
return m_menuItemIconSize;
}
// if we don't return size before QDockWidgets are created,
// any of the widgets with custom stylesheet are rendered with huge float,close buttons
// see void TableBrowserDock::setFocusStyle
return m_smallIconSize;
}
#endif
return QProxyStyle::pixelMetric(metric, option, widget);
}
private:
int m_toolBarIconSize;
#ifdef Q_OS_WIN
int m_menuItemIconSize;
int m_smallIconSize;
#endif
};
void printArgument(const QString& argument, const QString& description)
{
const int fieldWidth = 20;
@@ -32,11 +82,11 @@ Application::Application(int& argc, char** argv) :
QApplication(argc, argv)
{
// Get 'DB4S_SETTINGS_FILE' environment variable
const char* env = getenv("DB4S_SETTINGS_FILE");
const auto env = qgetenv("DB4S_SETTINGS_FILE");
// If 'DB4S_SETTINGS_FILE' environment variable exists
if(env)
Settings::setUserSettingsFile(QString::fromStdString(env));
if(!env.isEmpty())
Settings::setUserSettingsFile(env);
for(int i=1;i<arguments().size();i++)
{
@@ -44,10 +94,10 @@ Application::Application(int& argc, char** argv) :
{
if(++i < arguments().size())
{
if(env)
if(!env.isEmpty())
{
qWarning() << qPrintable(tr("The user settings file location is replaced with the argument value instead of the environment variable value."));
qWarning() << qPrintable(tr("Ignored environment variable(DB4S_SETTINGS_FILE) value : ") + QString::fromStdString(env));
qWarning() << qPrintable(tr("Ignored environment variable(DB4S_SETTINGS_FILE) value : ") + env);
}
Settings::setUserSettingsFile(arguments().at(i));
}
@@ -231,6 +281,10 @@ Application::Application(int& argc, char** argv) :
return;
}
// Set StyleProxy
QScreen *screen = primaryScreen();
setStyle(new DB4SProxyStyle(18, screen != nullptr ? screen->logicalDotsPerInch() : 96, style()));
// Show main window
m_mainWindow = new MainWindow();
m_mainWindow->show();
+10 -2
View File
@@ -50,9 +50,17 @@ void TableBrowserDock::setFocusStyle(bool on)
{
// Highlight title bar when dock widget is active
if(on)
setStyleSheet("QDockWidget::title {background:palette(highlight);}");
setStyleSheet(QStringLiteral(
"QDockWidget::title {"
"background:palette(AlternateBase);"
"text-align: center;"
"border-bottom: 2px solid palette(highlight);"
"}"));
else
setStyleSheet(QString());
setStyleSheet(QStringLiteral(
"QDockWidget::title {"
"text-align: center;"
"}"));
}
void TableBrowserDock::showContextMenuTableBrowserTabBar(const QPoint& pos)
+3 -28
View File
@@ -2,7 +2,6 @@
#include "Application.h"
#include "sqlite.h"
#include <QMessageBox>
#include <QProxyStyle>
static QString message = QString();
@@ -28,36 +27,15 @@ void boxMessageOutput(QtMsgType, const QMessageLogContext &, const QString &msg)
message += msg + "\n";
}
class DB4SProxyStyle final : public QProxyStyle {
public:
DB4SProxyStyle(int toolBarIconSize)
: QProxyStyle(nullptr), toolBarIconSize_(toolBarIconSize) {}
int pixelMetric(QStyle::PixelMetric metric,
const QStyleOption *option = nullptr,
const QWidget *widget = nullptr) const override {
if (metric == QStyle::PM_ToolBarIconSize) {
return toolBarIconSize_;
}
return QProxyStyle::pixelMetric(metric, option, widget);
}
private:
int toolBarIconSize_;
};
int main( int argc, char ** argv )
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
#endif
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#ifdef Q_OS_WIN
// In Windows, there is no output to terminal for a graphical application, so we install
// the output to message box, until the main window is shown or the application exits.
@@ -67,9 +45,6 @@ int main( int argc, char ** argv )
// Create application object. All the initialisation stuff happens in there
Application a(argc, argv);
// Set default QToolbar->iconSize via StyleProxy
a.setStyle(new DB4SProxyStyle(16));
// If there has been invocations to the message handler, show it to user in a message box.
if(!message.isEmpty()) {
QMessageBox messageBox;