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; }