Qt主窗口与QOpenGLWIdget在视网膜显示显示错误的大小

Qt MainWindow with QOpenGLWIdget in Retina display displays wrong size

本文关键字:显示 错误 视网膜 窗口 QOpenGLWIdget Qt      更新时间:2023-10-16

我有一个Qt应用程序与MainWindow

我在其中嵌入了一个QOpenGLWidget。一切都很好,直到我开始使用苹果视网膜显示器并在高DPI模式下运行我的应用程序:我的QOpenGLWidget只是它应该有的大小的1/4(即,它只填充了它应该填充的区域的左下角)。这个小部件正在显示原始的OpenGL数据(实际上是一个OpenSceneGraph上下文)

我能做什么来解决这个问题?

发现现在最好的选择,对于OpenGL相关的小部件和事件,是使用QPaintDevice::devicePixelRatio() (http://doc.qt.io/qt-5/qpaintdevice.html#devicePixelRatio)

这意味着将使用像素坐标的所有内容相乘,即鼠标事件、调整大小事件等。例子:

void MyGLWidget::resizeGL(int width, int height) {
  width *= Application::desktop()->devicePixelRatio(); 
  height *= Application::desktop()->devicePixelRatio(); 
  ...
  // Continue with previous code
}

在Retina/HighDPI显示器的低分辨率模式下运行时,或者在常规显示器中运行时,该比率为1,因此对我来说这似乎是便携式的。

From Qt docs (section OsX),

注意:缩放不适用于Open GL窗口

我没有在Mac电脑上尝试这种方法,但它在我的Windows电脑上解决了同样的问题。我不确定这是否是最好的解决方案,不过,可能有更简单的解决方案。试着看看它是否有效。

主要思想是手动缩放您的OpenGL内容大小。

First,定义要执行的缩放量。您可以使用物理点每英寸的特性:

QApplication app(argc, argv);    
int x = QApplication::desktop()->physicalDpiX();
int y = QApplication::desktop()->physicalDpiY();
// values 284 and 285 are the examples of reference values that we determined when DPI scaling was disabled
double scaleX = 284.0/double(x);
double scaleY = 285.0/double(y);

physicalDpi*可以判断一英寸有多少像素。为了定义比例,检测密度的参考值是多少,然后根据物理设备的密度按比例缩放(下一步)。

第二个,你必须在QOpenGLWidget中使用scaleXscaleY,并确保我们手动缩放:

  • 大小如QOpenGLWidget::width()QOpenGLWidget::height()将变成this->width()*m_scaleXthis->height()*m_scaleY
  • 鼠标事件坐标,如event->x()*m_scaleXevent->y()*m_scaleY