Qt4 高分屏适配工具函数

QString fitStyle(const QString & style, qreal scale)
	{
		if (style.isEmpty())
		{
			return style;
		}
		QString tempStyle = style;
		QRegExp rx("\\d+px", Qt::CaseInsensitive);
		rx.setMinimal(true);
		int index = -1;
		while ((index = rx.indexIn(tempStyle, index + 1)) >= 0)
		{
			int capLen = rx.cap(0).length() - 2;
			QString snum = tempStyle.mid(index, capLen);
			snum = QString::number(qRound(snum.toInt() * scale));
			tempStyle.replace(index, capLen, snum);
			index += snum.length();
			if (index > tempStyle.size() - 2)
			{
				break;
			}
		}
		return tempStyle;
	}
	void fitWidget(QWidget *widget, qreal scale)
	{
		if (widget)
		{
			QWidget *parentWid = widget->parentWidget();
			if (widget->inherits("QLineEdit") && parentWid && (parentWid->inherits("QAbstractSpinBox") || parentWid->inherits("QComboBox")))
			{
				return;
			}
			QSizePolicy sizePolicy = widget->sizePolicy();
			QSizePolicy::Policy horizontalPolicy = sizePolicy.horizontalPolicy();
			QSizePolicy::Policy verticalPolicy = sizePolicy.verticalPolicy();
			QRect geometry = widget->geometry();
			int fixW = geometry.width();
			int fixH = geometry.height();
			if (widget->inherits("QStackedWidget"))
			{
				// TODO
			}
			else
			{
				if (horizontalPolicy != QSizePolicy::Expanding && horizontalPolicy != QSizePolicy::Preferred)
				{
					fixW = qRound(geometry.width() * scale);
					widget->setFixedWidth(fixW);
				}
				if (verticalPolicy != QSizePolicy::Expanding && verticalPolicy != QSizePolicy::Preferred)
				{
					fixH = qRound(geometry.height() * scale);
					widget->setFixedHeight(fixH);
				}
			}
			if (!widget->inherits("QDialog"))
			{
				widget->setGeometry(QRect(qRound(scale * geometry.left()), qRound(scale * geometry.top()), fixW, fixH));
			}
			if (widget->inherits("QAbstractButton"))
			{
				if (QAbstractButton *button = qobject_cast<QAbstractButton *>(widget))
				{
					QSize iconSize = button->iconSize();
					button->setIconSize(QSize(qRound(iconSize.width() * scale), qRound(iconSize.height() * scale)));
				}
			}
			QSize maxSize = widget->maximumSize();
			if (maxSize.width() < fixW || maxSize.height() < fixH)
			{
				widget->setMaximumSize(fixW, fixH);
			}
			fitLayout(widget->layout(), scale);
		}
	}
#if QT_VERSION < 0x050000
	class _FakeQSpacerItem : public QLayoutItem
	{
	public:
		int width;
		int height;
		QSizePolicy sizeP;
		QRect rect;
	};
#endif
	void fitLayout(QLayout *layout, qreal scale)
	{
		if (!layout)
		{
			return;
		}
		auto margin = layout->contentsMargins();
		layout->setContentsMargins(qRound(margin.left() * scale), qRound(margin.top() * scale), qRound(margin.right() * scale), qRound(margin.bottom() * scale));
		layout->setSpacing(qRound(layout->spacing() * scale));
		for (int index = 0; index < layout->count(); ++index)
		{
			auto item = layout->itemAt(index);
			if (auto spacerItem = item->spacerItem())
			{
				QSize size = spacerItem->sizeHint();
#if QT_VERSION >= 0x050000
				QSizePolicy sizeP = spacerItem->sizePolicy();
#else
				auto fakeSpacerItem = reinterpret_cast<_FakeQSpacerItem *>(spacerItem);
				QSizePolicy sizeP = fakeSpacerItem->sizeP;
#endif
				// 仅处理这两种情况
				if (layout->inherits("QHBoxLayout") || layout->inherits("QVBoxLayout"))
				{
					spacerItem->changeSize(qRound(size.width() * scale), qRound(size.height() * scale), sizeP.horizontalPolicy(), sizeP.verticalPolicy());
				}
			}
			else if (auto widgetItem = item->widget())
			{
				fitWidget(widgetItem, scale);
			}
			else if (auto layoutItem = item->layout())
			{
				fitLayout(layoutItem, scale);
			}
		}
	}
	void fitWidgetAndStyle(QWidget *widget, qreal scale)
	{
		if (!widget)
		{
			return;
		}
		QString style = widget->styleSheet();
		if (!style.isEmpty())
		{
			widget->setStyleSheet(fitStyle(style, scale));
		}
		foreach(QWidget *childWidget, widget->findChildren<QWidget *>())
		{
			style = childWidget->styleSheet();
			if (!style.isEmpty())
			{
				childWidget->setStyleSheet(fitStyle(style, scale));
			}
		}
		fitWidget(widget, scale);
	}
	HdpiAdapter::HdpiAdapter(QWidget *pWidget)
		: QObject(pWidget)
	{
		if (pWidget)
		{
			pWidget->installEventFilter(this);
		}
	}
	bool HdpiAdapter::eventFilter(QObject *watched, QEvent *event)
	{
		if (event->type() == QEvent::Show && watched == parent())
		{
			if (QWidget *pWidget = qobject_cast<QWidget *>(watched))
			{
				pWidget->removeEventFilter(this);
				qreal dpi = QStyle::dpi();
				if (QStyle::dpi() > gs_hDpi || qFuzzyCompare(dpi, gs_hDpi))
				{
					fitWidgetAndStyle(pWidget, dpi);
				}
			}
		}
		return false;
	}

 

发表回复