在Retina显示屏上使用QOpenGLWidget的Qt MainWindow显示尺寸错误

4
我有一个带有MainWindow的Qt应用程序。 我在其中嵌入了一个QOpenGLWidget。一切都很好,直到我开始使用苹果Retina显示器并在高DPI模式下运行我的应用程序:我的QOpenGLWidget只有原本大小的1/4(也就是说,它只填充了它应该填充的区域的左下角部分)。该小部件正在显示原始OpenGL数据(实际上是OpenSceneGraph上下文)。 我该怎么做来解决这个问题?

你说的大小缩小1/4是指什么?是指部件没有填满其指定区域,还是GL视图中的内容没有填满部件区域?你在部件中显示什么?原始的OpenGL吗?也许你可以用一张截图来说明。 - ypnos
@ypnos将问题更改为回答,感谢您的关注 :) - manatttta
我明白了。那么你提供了正确的答案解决了你的问题,而vicrucann也指出了正确的问题。我建议您接受您自己的答案。 - ypnos
2个回答

6

发现目前处理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/高DPI显示器上以低分辨率模式运行或在普通显示器上运行时,此比率为1,因此这对我来说似乎是可移植的。


3

来自Qt文档(OsX部分):Qt文档

注意:缩放不适用于OpenGL窗口。

我没有在Mac上尝试过这种方法,但它对我的Windows机器上的相同问题有所帮助。虽然我不确定这是最好的解决方案,也许有更简单的解决方案。请尝试并查看是否有效。

首先,定义要执行的比例量。您可以使用每英寸物理点的特征:

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

1
谢谢!根据您的回答,我找到了devicePixelRatio,我认为它直接实现了我的需求。 - manatttta
1
很高兴能帮上忙。devicePixelRatio看起来确实更整洁。我认为手动计算的scaleXscaleY会略微更精确。在我的机器上,它们分别为2.0和~2.02;而devicePixelRatio将为两个维度提供2.0的值。不确定差异有多明显,但有两种选择很不错。 - vicrucann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接