""" Qt.AA_EnableHighDpiScaling scaling behavior broken if all screens have a scale factor of < 150% on startup Repro steps: 1) Set all screens to 100% or 125% scaling. 2) Launch this app. 3) Press the button. Note the geometry, scale factors, etc. that are printed. 4) Change the scaling on the screen with the app. Expected: the app and its contents scales appropriately. Actual: it doesn't. Notice the debug output for the screens. If the ratios are reported as 1.0 initially, they will remain that way regardless of changes to scaling factors on any screen. The argument to the logicalDotsPerInchChanged will be 96.0 * whatever the scale factor is set to--this is the same behavior as when the Qt.AA_EnableHighDpiScaling is NOT set. If at least one of the ratios was reported as > 1.0, then the reported ratios will change with scaling changes. The argument to the logicalDotsPerInchChanged will always be 96.0. """ import sys # Must pip install PySide2 from PySide2.QtCore import ( QCoreApplication, QEvent, QRect, QSize, Qt, Slot, ) from PySide2.QtGui import ( QFont, ) from PySide2.QtWidgets import ( QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, ) import win32gui class MainWindow(QWidget): def __init__(self, parent=None): super().__init__(parent) # Create button self.button = QPushButton("Show Greetings") font = QFont("Segoe UI") font.setPointSizeF(24) self.button.setFont(font) # Create layout and add button layout = QVBoxLayout() layout.addWidget(self.button) layout.setAlignment(self.button, Qt.AlignHCenter | Qt.AlignCenter) # Set layout self.setLayout(layout) # Add button signal to greetings slot self.button.clicked.connect(self.on_click) for screen in QApplication.screens(): screen.logicalDotsPerInchChanged.connect(self.on_dpi_changed) self.dump('__init__') def on_dpi_changed(self, dpi: float) -> None: self.dump('on_dpi_changed ' + str(dpi)) def dump_screens(self): for index, screen in enumerate(QApplication.instance().screens()): print('screen {} ratio {} geometry {},{},{},{} size {},{}'.format( index, screen.devicePixelRatio(), screen.geometry().left(), screen.geometry().top(), screen.geometry().right(), screen.geometry().bottom(), screen.size().width(), screen.size().height(), )) def dump_widget(self, widget, name): left, top, right, bottom = win32gui.GetWindowRect(widget.winId()) actual_width = right - left actual_height = bottom - top ratio = widget.devicePixelRatio() if actual_width == ratio * widget.width() and actual_height == ratio * widget.height(): status = 'consistent' else: status = 'INCONSISTENT' print("{}: virtual px {},{} ratio {} actual px {},{} {}".format( name, widget.width(), widget.height(), ratio, actual_width, actual_height, status, ) ) def on_click(self): self.dump('click') def dump(self, caption=None): if caption: print(caption) self.dump_widget(self, 'window') self.dump_widget(self.button, 'button') self.dump_screens() print() if __name__ == '__main__': QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) # Create the Qt Application app = QApplication(sys.argv) # Create and show the MainWindow main = MainWindow() main.show() # Run the main Qt loop sys.exit(app.exec_())