这里仅大概描述一下实现思路。
运行条件
- 两个屏幕,分辨率不同。
- Qt软件
问题提出
前段时间写了一个软件,窗口内有自绘内容。
自绘内容里面用的长度单位都是像素。可想而知,在开发者的电脑屏幕上大小都是符合要求的。到这一步都没问题。
软件开发完成后发给客户,客户在他的电脑上运行,也没问题,毕竟分辨率差不多。
偶然一次使用配有高分辨率显示器电脑运行软件,在4k屏下,软件出现了以下问题:
- 整体尺寸和某些自绘内容(线条形状)变得很小,原因是屏幕分辨率升高了,像素更密集,相同个数的像素长度看起来更短,这个比较好理解。
- 除了某些自绘的内容外,比如文字,却没有变小。这是因为在绘制文本的时候,字体设置大小使用了setPointSize,使得文本绘制在任何显示器上都具有相同的大小。
- 最终的显示结果是,文字看起来很大,图形变得很小。
解决方法
实现多屏幕分辨率自适应
这里分两种情况讨论。
- 只使用一块屏幕
这种情况下,只需要做以下工作:
- 绘制图形时,以毫米为单位绘制。
- 获取屏幕分辨率,添加长度->像素转换函数,将每个长度都转换成像素长度再传递给绘制函数。
这样就可以实现不同分辨率下自绘内容自适应。
- 使用多个分辨率不同屏幕
这种情况下,涉及到窗口拖拽的问题。
当软件窗口从一个窗口拖拽到另外一个窗口时,需要重新排版。
需要做以下工作:
- 设计窗口分辨率改变通知信号
在Qt中没有找到相关的通知机制,我们可以在paint函数中检测窗口的当前屏幕是否改变,如果发生改变,则发出一个信号。下面是一段实现代码,用于判断主屏幕是否改变:
bool Global::checkIfScreenChanged()
{static int screen_number = -1;bool changed = false;QWidget *w = mainWindow();QDesktopWidget *dk = QApplication::desktop();int new_screen_number = dk->screenNumber(w);if (screen_number != new_screen_number){screen_number = new_screen_number;changed = true;// 发出通知emit sigScreenChanged(screen_number);}return changed;
}
- 重新布局和绘制
接收到窗口屏幕改变消息后,进行重新布局、绘制。
实现效果
达到了预期效果。
结语
Windows上的软件,比如office、WPS都对多分辨率多屏幕进行了处理,可以将上述任意软件打开后从一个窗口拖动到另外一个窗口,在跨越屏幕的瞬间,软件会进行重新布局。和我们使用本文方法实现的效果相同。
最近创建了一个公众号,定期写写文章,主要是Qt相关的。如果您觉得文章有用,可以关注一下。