soqt icon indicating copy to clipboard operation
soqt copied to clipboard

high res screen problems

Open VolkerEnderlein opened this issue 5 years ago • 1 comments

Original report by Jonathan Le Vallois (Bitbucket: JLeVallois, GitHub: JLeVallois).

Attachments: SoQtGLWidget.cpp | SoQtGLWidgetP.h


When using a QApplication with AA_EnableHighDpiScaling scaling of icons etc works fine for different screen resolutions, but the viewer area created via SoQtExaminerViewer does not scale correctly. In fact it is blank on high res screens.

This can largely be fixed by changing part of the definition of SoQtGLWidget::setGLSize() as follows:

if (PRIVATE(this)->currentglwidget) { int frame = this->isBorder() ? PRIVATE(this)->borderthickness : 0; PRIVATE(this)->currentglwidget->setGeometry(QRect(frame, frame, PRIVATE(this)->glSize[0], PRIVATE(this)->glSize[1])); #if QT_VERSION >= 0x050000 PRIVATE(this)->glSize = PRIVATE(this)->glSizeUnscaled * PRIVATE(this)->currentglwidget->devicePixelRatio(); #endif }

i.e. moving the line of code that does the scaling of glSize to after the call of setGeometry.

I also found it necessary to add

#define QT_CLEAN_NAMESPACE 1

before the includes in SoQtGLWidgetP.h

These changes work for simple test cases and our much more complex code.

There still remains an issue with dragging the viewer from one screen to another with a different resolution. In this case the viewing area is not resized correctly in that what it contains disappears from view. As a workaround this can be corrected by maximizing and un-maximizing the program panel.

VolkerEnderlein avatar Jul 26 '18 13:07 VolkerEnderlein

Here is a minimal example (C++ and CMake) to visualize this issue. In order to test this in a non-HiDPI screen, the environment variable QT_SCALE_FACTOR can be used, e.g., on Windows with set QT_SCALE_FACTOR=2 before running the example.

#include <QApplication>
#include <QWidget>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/Qt/SoQt.h>
#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>

int
main(int argc, char** argv)
{
	QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
	QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
	
	QWidget* widget = SoQt::init(argc, argv, argv[0]);
	widget->resize(640, 480);
	
	SoSeparator* root = new SoSeparator();
	root->ref();
	
	SoCone* cone = new SoCone();
	root->addChild(cone);
	
	SoQtExaminerViewer* viewer = new SoQtExaminerViewer(widget);
	viewer->setSceneGraph(root);
	
	SoQt::show(widget);
	SoQt::mainLoop();
	
	root->unref();
	
	return 0;
}
cmake_minimum_required(VERSION 2.8.11)

project(testSoQtHiDpi)

find_package(OpenGL REQUIRED)
find_package(Qt5 COMPONENTS Core Gui OpenGL Widgets QUIET)
find_package(SoQt REQUIRED)

set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

add_executable(testSoQtHiDpi testSoQtHiDpi.cpp)

target_link_libraries(testSoQtHiDpi ${OPENGL_LIBRARIES} ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5OpenGL_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${SoQt_LIBRARIES})

With set QT_SCALE_FACTOR=1, the result is as expected:

scale_factor_1

With set QT_SCALE_FACTOR=1.5, the window size does not match:

scale_factor_1_5

With set QT_SCALE_FACTOR=2, the screen appears completely black:

scale_factor_2

The patch in roboticslibrary/soqt@72c62073656780df44e63395596cf1f6966eb6ed solves these issues, but there are additional issues with multiple screens of different DPI factors that can be tested via QT_SCREEN_SCALE_FACTORS, e.g., set QT_SCREEN_SCALE_FACTORS=1;1.5.

rickertm avatar Mar 18 '20 19:03 rickertm