如何阻止显示分辨率影响 pyqtgraph 图中的轴

How to stop display resolution from affecting axes in pyqtgraph plots

我正在使用 pyqtgraph 绘制一些数据并注意到当我将绘图从我的笔记本电脑屏幕移动到第二台显示器时,绘图的缩放比例受到影响:

笔记本电脑显示器:

外接显示器:

请注意坐标轴被“压缩”了,绘图在第二台显示器上不再正确缩放。

我发现其他人在网络上报告了类似的问题,但找不到任何真正的解决方案。建议的一种解决方案是使监视器的分辨率相同。我不喜欢这个解决方案,因为我不得不牺牲笔记本电脑的分辨率来适应分辨率较低的外接显示器。

我发现的另一个解决方案是在如下所示实例化 Qapplication 之前将行 app.setAttribute(QtCore.Qt.AA_Use96Dpi) 添加到主循环中,据称让 Qt 忽略 OS 的 DPI 设置:

def main():
 import sys
 app = QtWidgets.QApplication(sys.argv)
 app.setAttribute(QtCore.Qt.AA_Use96Dpi)
 MainWindow =GraphWindow()
 MainWindow.show()
 sys.exit(app.exec_())

这乍一看似乎可行,因为绘制的数据在轴上正确缩放。然而,它似乎并没有真正起作用——添加这条线会影响笔记本电脑上轴的缩放比例,如下所示(相同的数据现在绘制在 x 轴上跨越 0 到 7000 的轴上,并且 - Y轴上2至-26dB):

,

但确实“解决”了将绘图移动到第二台显示器时的问题,使其看起来像上面显示的第一个“原始”笔记本电脑绘图。

这尤其令人担忧,因为在 app.setAttribute(QtCore.Qt.AA_Use96Dpi) 指令“看起来”正确之后的膝上型电脑输出的情况下,却歪曲了实际数据。当我第一次绘制数据时,我可能很容易错过这个包含这条指令。

无论 OS 的 DPI 设置和显示器分辨率如何,正确显示绘图的正确方法是什么?非常奇怪的是,绘制的数据似乎与轴值无关。

这是一个最小的可重现样本:

from PyQt5 import QtWidgets, QtCore
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys  # We need sys so that we can pass argv to QApplication
import os
from  numpy.random import seed
from  numpy.random import randint

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.graphWidget = pg.PlotWidget()
        self.setCentralWidget(self.graphWidget)

        x = [1,2,3,4,5,6,7,8,9,10]
        seed(1)
        y = randint(5,35,10)

        # plot data: x, y values
        self.graphWidget.plot(x, y)


def main():
    app = QtWidgets.QApplication(sys.argv)
    app.setAttribute(QtCore.Qt.AA_Use96Dpi)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

可以在这里找到答案:https://github.com/pyqtgraph/pyqtgraph/issues/756

这个问题的快速总结: 基本上有两种方法可以解决这个问题。

  1. 让您的应用程序具有 DPI 感知能力(Androwei)
import ctypes
import platform

def make_dpi_aware():
    if int(platform.release()) >= 8:
        ctypes.windll.shcore.SetProcessDpiAwareness(True)

# add this code before "app = QtWidgets.QApplication(sys.argv)"
make_dpi_aware()
  1. Qt.HighDpiScaleFactorRoundingPolicy 设置为 PassThrough(作者:andybarry)
# add this code before "app = QtWidgets.QApplication(sys.argv)"
QtWidgets.QApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)

我都试过了,它们都很完美!感谢这些贡献者。希望你也能发现它有用。

setAttribute 解决方案从来没有以这种方式为我工作,windll 操作使 gui 模糊...

在 app = QApplication(sys.argv) 之前添加以下两行解决了我的问题:

QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)