当前位置: 首页 > news >正文

QT多屏显示程序

多屏显示的原理其实很好理解,就拿横向扩展来说:
计算机把桌面的 宽度扩展成了 w1(屏幕1的宽度) + w2(屏幕2的宽度) 。
当一个窗口的起始横坐标 > w1,则 他就被显示在第二个屏幕上了。

多屏虚拟成一个桌面,QScreen Class。qtbase/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp

QT可用的平台插件有:xcb、eglfs、linuxfb、minimal、minimalegl、offscreen、vnc、wayland-egl、wayland、wayland-xcomposite-egl、wayland-xcomposite-glx、webgl等

 

qt的说明文档中用一张图阐述了这个情况:
 

在这里插入图片描述


QApplication 提供了一个获得virtual desktop的方法:
QDesktopWidget *desktop = QApplication::desktop();
返回的 QDesktopWidget 存储着当前桌面的信息。

注意 ,这个函数必须在创建了 QApplication 对象之后才能使用, 否则会出错。具体原因,要问qt。

这个desktop有几个很有用的函数,用来获取当前的屏幕状态和分辨率
1) int desktop->primaryScreen()
获取主屏幕的索引序号,(windows开始菜单所在的屏幕为主屏幕), 每个副屏幕序号+1

2) int desktop->screenCount()
获取当前屏幕个数

3) QRect desktop->screenGeometry(int screen_index)
根据当前的屏幕序号获取屏幕宽高等属性

4) int desktop->width()
获取虚拟屏幕全宽, 注意这个比较猛,是获取的总宽度,对于横向扩展屏来说,也就是 屏幕1+ 屏幕2 + … 的宽度
5) int desktop->height()
获取虚拟屏幕全高

下面的这个程序就可以测试多屏(只测了横屏,没测试纵屏): 根据当前屏幕数量n,生成n个窗口,每个窗口都占据了一个屏幕

#include "mainwindow.h"
#include <QApplication>
#include <QDesktopWidget>
#include <cstdio>
#include <QMessageBox>typedef struct{
int screen_no;
QRect rect;
}SCREEN;
SCREEN g_screens[10];int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QDesktopWidget *desktop = QApplication::desktop();int screen_count = desktop->screenCount();int prim_screen = desktop->primaryScreen();
char warning[100], *idx=warning;
for(int i=0; i<screen_count ;i++ ){
g_screens[i].screen_no = prim_screen + i;
g_screens[i].rect = desktop->screenGeometry(prim_screen + i);
sprintf(idx, "screen%d w[%d], h[%d] ",i, g_screens[i].rect.width(),g_screens[i].rect.height() );
idx += strlen(idx);
}
sprintf(idx, "total width[%d] , total height[%d] n", desktop->width(), desktop->height() );
QMessageBox::warning(NULL, "screen", warning, QMessageBox::Ok);MainWindow wnd[5];
for(int i=0; i < screen_count; i++){
wnd[i].resize(g_screens[i].rect.width(),g_screens[i].rect.height());
if(i == 0)
wnd[i].move(0,0);
else
wnd[i].move(i* g_screens[i-1].rect.width(),0);
char str[50];
sprintf(str,"this is screen %d",i);
wnd[i].show();
}
return app.exec();
}

想实现这样一种功能:主程序的主窗口在PC上显示,而其子dialog在另外的显示器上显示(做实验时方便监控且不会有多余的干扰)。

方法如下 :建立Qdesktopwidget对象
QDesktopWidget* desktop = Application::desktop();

获取当前显示器的个数

N = desktop->screenCount();

如果有两个显示,则N=2,qt默认的计算机主机的index = 0,外接显示器的index = 1;
QDialog 有个成员函数叫setGeometry,只需要将dialog对象的Geometry设置为index为1的显示器即可,默认为0.如果要显示的dialog的对象为mdlg,则
mdlg.setGeometry(desktop->screenGeometry(1));
mdlg.show();

#include <QDesktopWidget>//获取屏幕信息
QDesktopWidget* desktop = QApplication::desktop();      //获取屏幕对象(这个函数必须在创建了 QApplication 对象之后才能使用, 否则会出错)                                                                                         
int screenNum = desktop->screenCount();         		//获取屏幕个数                                                                                  
int mainScreenID = desktop->primaryScreen();    		//获取主屏幕索引,(windows开始菜单所在的屏幕为主屏幕),每个副屏幕序号+1    
QRect screenRect = desktop->screenGeometry(int screen_index);	//根据屏幕索引获取屏幕宽高等属性
int screenWidth = desktop->width();						//获取屏幕的宽
int screenWidth = desktop->height();					//获取屏幕的高                                                                                                                                                                                                                                                                                                                                                                                                         
for(int i=0; i<screenNum; ++i) {         				//获取每块屏幕分辨率                                                                                           qDebug()<<"屏幕"<<i+1<<"分辨率: "<<desktop->screenGeometry(i).size();                                                                
}                                                                                                                                   //======================================================================   
//设置对话框mdlg显示在副屏1的左上角坐标
QDialog mdlg;
mdlg.setGeometry(desktop->screenGeometry(1));  
mdlg.show();  
//======================================================================   
//如果想全屏显示在副屏1,则可以获取副屏1的分辨率,更新对话框的大小再设置坐标
mdlg.resize(desktop->screenGeometry(1).size());		//设置对话框全屏
mdlg.setGeometry(desktop->screenGeometry(1)); 		//设置对话框对齐副屏1左上角坐标
mdlg.show();  
//======================================================================                                                                                                                         
linuxfb实现多屏(QT5已废弃)

如果多屏对应一个fb
那么应该可以知道不同屏对应fb显示内存的位置,只要根据位置去画窗口即可

如果多屏对应不同的设备 fb,可以运行下面的命令来指定不同的fb在qt显示内存上的位置
./xxx -qws -display "Mutli:LinuxFb:0 LinuxFb:/dev/fb1:1:offset=0,1080"
xxx表示qt可执行文件
"Mutli:LinuxFb:0 LinuxFb:/dev/fb1:1:offset=0,1080"
表示有两个输出fb分别是 /dev/fb0, /dev/fb1,其中/dev/fb0的起始位置在 qt 显示内存的(0,0), /dev/fb1的起始位置在 qt 显示内存的(0,1080)
程序中(假设显示分辨率为1920x1080)
在(0,0)到(1920,1080)范围内画窗口就显示在fb0上,在(0,1080)到 (1920,2160)范围画窗口就显示在fb1上

引申:内核态分配内存虚拟出一个fb0,操作fb0时,内核态程序将fb0内存复制到fb1和fb2内存中(前提是fb1和fb2的内核态地址即物理地址连续,且物理地址最好是固定的)。实际验证?

利用Qt实现双屏显示

前提是设备中有两个屏幕。这样在linux中Qt实现双屏显示就很简单了。只需要把窗口利用move函数移动到另一个屏幕的像素点就可以了。例如:一屏分辨率为:1280 * 800 ,二屏分辨率为:800 * 480。
(1)如果你定义了一个 1600 * 800的窗口,比一屏多出来400个像素点就会自动在二屏中显示,不用任何处理(前提是你到设备双屏能够正常运行)
(2)如果想在一屏的基础上点击一个按钮弹出一个窗口,而这个窗口想要在二屏上显示,就需要利用move函数,把这个对话框的位置移动到二屏上显示:move(1280,0);

对于上面的情况(1)(2),在linux上亲测没有问题,但是在ARM平台上出现问题:在点击了按钮后,窗口并没有在二屏上显示,而是在一屏中显示,而且置于最底层(原来的窗口挡住了这个窗口,因此并不能显示出来)。

在ARM设备中正常双屏显示如下:

#ifdef DOUBLE_SCREENdesktop = QApplication::desktop();
int N = desktop->screenCount();
qDebug()<<"screen :"<<N;
qDebug()<<"screen1 rect:"<<desktop->screenGeometry(0);
qDebug()<<"screen2 rect:"<<desktop->screenGeometry(1);DoubleScreen *m_DoubleScreen = new DoubleScreen;
m_DoubleScreen->initLab(desktop->screenGeometry(1));
m_DoubleScreen->show();#endifvoid DoubleScreen::initLab(QRect rect)
{setGeometry(rect);this->resize(800,480);lab=new QLabel("this is desktop"+QString::number(num+1),this);lab->setGeometry(0,0,rect.width(),rect.height());lab->setAlignment(Qt::AlignCenter) ;}

上述代码中DoubleScreen为继承QMainWindow的类,而initLab为他到成员函数,将二屏的rect作为initLab的参数传递进来,然后通过setGeometry()函数就能将DoubleScreen的窗口显示在二屏上了。

相关文章:

QT多屏显示程序

多屏显示的原理其实很好理解&#xff0c;就拿横向扩展来说&#xff1a; 计算机把桌面的 宽度扩展成了 w1&#xff08;屏幕1的宽度&#xff09; w2(屏幕2的宽度) 。 当一个窗口的起始横坐标 > w1&#xff0c;则 他就被显示在第二个屏幕上了。 多屏虚拟成一个桌面&#xff0…...

python使用xlwt时,报ValueError: More than 4094 XFs (styles)

在写表格时&#xff0c;遇到如下报错 一、报错原因 xlwt最多只能有4094个样式&#xff0c;超出这个样式数量就报错了。 二、解决办法 &#xff08;1&#xff09;去掉样式的要求...

GitHub 打不开解决方案

GitHub 这几年国内普通用户越来越难以访问&#xff0c;github 作为全球最大的开源平台&#xff0c;里面有用的内容很多&#xff0c;不管是对专业用户还是普通用户&#xff0c;无法访问都是很严重的问题。 1.GitHub 加速镜像 kgithub 是一个公益加速项目&#xff0c;仅需在 gi…...

Java网络编程(一)网络基础

概述 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递 网络分类 局域网(LAN) 局域网是一种在小区域内使用的,由多台计算机组成的网络,覆盖范围…...

matlab使用教程(17)—多项式的定义和运算

1.创建并计算多项式 此示例说明如何在 MATLAB 中将多项式表示为向量以及根据相关点计算多项式。 1.1 表示多项式 MATLAB 将多项式表示为行向量&#xff0c;其中包含按降幂排序的系数。例如&#xff0c;三元素向量 p [p2 p1 p0]; 表示多项式 创建一个向量以表示二次多项式…...

华为认证 | 这门HCIA认证正式发布!

华为认证云服务工程师HCIA-Cloud Service V3.5&#xff08;中文版&#xff09;自2023年8月11日起&#xff0c;正式在中国区发布。 01 发布概述 基于“平台生态”战略&#xff0c;围绕“云-管-端”协同的新ICT技术架构&#xff0c;华为公司打造了覆盖ICT领域的认证体系&#xf…...

【Docker】Docker安装 MySQL 8.0,简洁版-快速安装使用

今天&#xff0c;使用docker安装mysql数据库进行一个测试&#xff0c;结果网上找了一篇文章&#xff0c;然后。。。。坑死我… 特总结本篇安装教程&#xff0c;主打一个废话不多说&#xff01; 坑&#xff1a;安装成功&#xff0c;客户端工具连接不上数据库》。。。 正文&…...

CSS自己实现一个步骤条

前言 步骤条是一种用于引导用户按照特定流程完成任务的导航条&#xff0c;在各种分步表单交互场景中广泛应用。例如&#xff1a;在HIS系统-门诊医生站中的接诊场景中&#xff0c;我们就可以使用步骤条来实现。她的执行步骤分别是&#xff1a;门诊病历>遗嘱录入>完成接诊…...

Visual Studio 2019 解决scanf函数报错问题

前言 Visual Studio 2019 解决scanf函数报错问题 博主博客链接&#xff1a;https://blog.csdn.net/m0_74014525 关注博主&#xff0c;后期持续更新系列文章 *****感谢观看&#xff0c;希望对你有所帮助***** 系列文章 第一篇&#xff1a;Visual Studio 2019 详细安装教程&…...

亚马逊无限买家号如何注册?

如果想要拥有大批量的亚马逊买家号&#xff0c;可以使用亚马逊鲲鹏系统进行自动注册操作。在注册之前我们需要先准备好账号所需要的资料&#xff1b; 1、Ip&#xff1a;软件系统支持11个亚马逊站点使用&#xff0c;因此注册哪一个国家的买家号时就需要购买相应国家的ip&#x…...

前端框架学习-ES6新特性(尚硅谷web笔记)

ECMASript是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。javaScript也是该规范的一种实现。 新特性目录 笔记出处&#xff1a;b站ES6let 关键字const关键字变量的解构赋值模板字符串简化对象写法箭头函数rest参数spread扩展运算符Promise模块化 ES8async 和 await E…...

普陀发布新规服务元宇宙企业 和数软件发展元宇宙场景落地

近日&#xff0c;数智中国AIGC科技周2023全球元宇宙大会上海站活动现场“半马苏河”元宇宙企业科创政策包正式发布。政策包在普陀原有科创政策基础上进行了叠加升级&#xff0c;一共涵盖了十条专项服务元宇宙企业的专项政策&#xff0c;简称普陀“元十条”。 普陀“元十条”从…...

Kotlin差异化分析,let,run,with,apply及also

作用域函数是Kotlin比较重要的一个特性&#xff0c;共分为以下5种&#xff1a;let、run、with、apply 以及 also&#xff0c;这五个函数的工作方式可以说非常相似&#xff0c;但是我们需要了解的是这5种函数的差异&#xff0c;以便在不同的场景更好的利用它。 读完这篇文章您将…...

(stm32)低功耗模式

低功耗模式 执行哪个低功耗模式的程序判断流程 标志位设置操作一定要在WFI/WFE之前&#xff0c;调用此指令后立即进入睡眠判断流程 模式对比 睡眠模式 停止模式 待机模式...

【C++学习手札】一文带你认识C++虚函数(内层剖析)

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f340;本文前置知识&#xff1a; C初识继承 ♈️今日夜电波&#xff1a;No title —REOL 1:02 ━━━━━━️&#x1f49f;──────── 4:03 …...

Python“牵手”1688商品评论数据采集方法,1688API申请指南

1688平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范&#xff0c;1688API接口是指通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问1688平台的数据&#xff0c;包括商品信息、店铺信息、物流信息等&#xff0c;从而实现1688平台…...

“深入解析JVM内部机制:探秘Java虚拟机的奥秘“

标题&#xff1a;深入解析JVM内部机制&#xff1a;探秘Java虚拟机的奥秘 摘要&#xff1a;本文将深入解析JVM&#xff08;Java虚拟机&#xff09;的内部机制&#xff0c;从字节码执行到垃圾回收&#xff0c;逐步揭示Java程序运行的奥秘。通过理论分析和示例代码&#xff0c;读…...

【系统工具】开源服务器监控工具WGCLOUD初体验

经常看到服务器上传下载流量一直在跑&#xff0c;也不知道是啥软件在偷偷联网~~~官网地址&#xff1a;www.wgstart.com&#xff0c;个人使用是免费的。 WGCLOUD官网介绍 "WGCLOUD支持主机各种指标监测&#xff08;cpu使用率&#xff0c;cpu温度&#xff0c;内存使用率&am…...

powerBI应用技巧

power BI应用技巧 持续跟新 1.函数日期表 使用高级编辑器—M函数&#xff08;把下面代码直接复制即可&#xff09; 版本1&#xff1a;前单位写的M函数&#xff0c;日期是2021年开始的 letdate(optional 请输入开始年份 as number,optional 请输入结束年份 as number)>l…...

RK3568背光调试分享

一.PWM 驱动 驱动文件所在位置: drivers/pwm/pwm-rockchip.c 3.10 和 4.4 及以上版本内核下驱动文件名字是同一个, pwm-rockchip.c 只支持 Continuous mode , 但是里面的代码有些差别。 4.4 及以上内核版本将 pwm_config() , pwm_enable()...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

嵌入式面试常问问题

以下内容面向嵌入式/系统方向的初学者与面试备考者,全面梳理了以下几大板块,并在每个板块末尾列出常见的面试问答思路,帮助你既能夯实基础,又能应对面试挑战。 一、TCP/IP 协议 1.1 TCP/IP 五层模型概述 链路层(Link Layer) 包括网卡驱动、以太网、Wi‑Fi、PPP 等。负责…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema&#xff0c;不需要复杂的查询&#xff0c;只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 &#xff1a;在几秒钟…...

RabbitMQ 各类交换机

为什么要用交换机&#xff1f; 交换机用来路由消息。如果直发队列&#xff0c;这个消息就被处理消失了&#xff0c;那别的队列也需要这个消息怎么办&#xff1f;那就要用到交换机 交换机类型 1&#xff0c;fanout&#xff1a;广播 特点 广播所有消息​​&#xff1a;将消息…...

第2课 SiC MOSFET与 Si IGBT 静态特性对比

2.1 输出特性对比 2.2 转移特性对比 2.1 输出特性对比 器件的输出特性描述了当温度和栅源电压(栅射电压)为某一具体数值时,漏极电流(集电极电流...