QTabBar: enable high dpi moving of a tab

Moving tabs of a QTabBar goes through a temporary QWidget that
captures a "screenshot" of the tab, and then gets moved around.
Unfortunately, that screenshot was not using the devicePixelRatio,
resulting in blurry text and icons. For some reason, setting
the DPR on the pixmap isn't enough -- that causes it to be
drawn twice as big (bug somewhere in Qt styles?).

Work around that by not using the palette, but a simple widget
which draws the pixmap (which also leads to somehow clean code).

Change-Id: Id12f9251625693d108031488ddfab86277128705
Task-number: QTBUG-50898
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Giuseppe D'Angelo 2016-03-21 19:40:46 +01:00
parent f64640f441
commit 95c9a0376e
2 changed files with 35 additions and 7 deletions

View File

@ -64,6 +64,23 @@
QT_BEGIN_NAMESPACE
QMovableTabWidget::QMovableTabWidget(QWidget *parent)
: QWidget(parent)
{
}
void QMovableTabWidget::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
update();
}
void QMovableTabWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
QPainter p(this);
p.drawPixmap(0, 0, m_pixmap);
}
inline static bool verticalTabs(QTabBar::Shape shape)
{
@ -1906,13 +1923,14 @@ void QTabBarPrivate::setupMovableTab()
{
Q_Q(QTabBar);
if (!movingTab)
movingTab = new QWidget(q);
movingTab = new QMovableTabWidget(q);
int taboverlap = q->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 ,q);
QRect grabRect = q->tabRect(pressedIndex);
grabRect.adjust(-taboverlap, 0, taboverlap, 0);
QPixmap grabImage(grabRect.size());
QPixmap grabImage(grabRect.size() * q->devicePixelRatioF());
grabImage.setDevicePixelRatio(q->devicePixelRatioF());
grabImage.fill(Qt::transparent);
QStylePainter p(&grabImage, q);
p.initFrom(q);
@ -1923,11 +1941,8 @@ void QTabBarPrivate::setupMovableTab()
p.drawControl(QStyle::CE_TabBarTab, tab);
p.end();
QPalette pal;
pal.setBrush(QPalette::All, QPalette::Window, grabImage);
movingTab->setPalette(pal);
movingTab->setPixmap(grabImage);
movingTab->setGeometry(grabRect);
movingTab->setAutoFillBackground(true);
movingTab->raise();
// Re-arrange widget order to avoid overlaps

View File

@ -61,6 +61,19 @@
QT_BEGIN_NAMESPACE
class QMovableTabWidget : public QWidget
{
public:
explicit QMovableTabWidget(QWidget *parent = Q_NULLPTR);
void setPixmap(const QPixmap &pixmap);
protected:
void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE;
private:
QPixmap m_pixmap;
};
class QTabBarPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QTabBar)
@ -201,7 +214,7 @@ public:
int switchTabCurrentIndex;
int switchTabTimerId;
QWidget *movingTab;
QMovableTabWidget *movingTab;
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
int previousPressedIndex;
#endif