QT多屏顯示程序

多屏顯示的原理其實很好理解,就拿橫向擴展來說:
計算機把桌面的 寬度擴展成了 w1(屏幕1的寬度) + w2(屏幕2的寬度) 。
當一個窗口的起始橫坐標 > w1,則 他就被顯示在第二個屏幕上了。

drm設備可以多用戶同時打開,FB獲取的用戶態虛擬內存地址映射到內核態物理內存地址也是不同的

多屏虛擬成一個桌面,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的窗口顯示在二屏上了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42301.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42301.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42301.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring MVC 簡介

目錄 1. 什么是MVC2. 什么是SpringMVC 1. 什么是MVC MVC是一種常用的軟件架構模式。可以看作是一種設計模式&#xff0c;也可以看作是一種軟件框架。經典MVC模式中&#xff0c;M是指模型&#xff0c;V是視圖&#xff0c;C則是控制器&#xff0c;使用MVC的目的是將M和V的實現代…

golang中使用chan控制協程并發簡單事例

func main() {processNum : 5ch : make(chan struct{}, processNum)for true {ch <- struct{}{}go func() {defer func() {<-ch}()fmt.Println("我是協程", time.Now().UnixNano())time.Sleep(time.Second * 5)}()} } 可以看到&#xff0c;這里每5s會執行一次帶…

Linux15 消息隊列 線程

目錄 1、進程間通信IPC&#xff1a; 2、多線程 3、向消息隊列中寫入數據 4、從消息隊列中讀取數據 5、多線程&#xff1a; 6、將多線程的數據返回給主…

數據庫索引優化策略與性能提升實踐

文章目錄 什么是數據庫索引&#xff1f;為什么需要數據庫索引優化&#xff1f;數據庫索引優化策略實踐案例&#xff1a;索引優化帶來的性能提升索引優化規則1. 前導模糊查詢不適用索引2. 使用IN優于UNION和OR3. 負向條件查詢不適用索引4. 聯合索引最左前綴原則5. 范圍條件查詢右…

c#實現策略模式

下面是一個使用C#實現策略模式的示例代碼&#xff1a; using System;// 策略接口 public interface IStrategy {void Execute(); }// 具體策略類A public class ConcreteStrategyA : IStrategy {public void Execute(){Console.WriteLine("具體策略A的執行邏輯");} …

【Mysql】MVCC版本機制的多并發

&#x1f307;個人主頁&#xff1a;平凡的小蘇 &#x1f4da;學習格言&#xff1a;命運給你一個低的起點&#xff0c;是想看你精彩的翻盤&#xff0c;而不是讓你自甘墮落&#xff0c;腳下的路雖然難走&#xff0c;但我還能走&#xff0c;比起向陽而生&#xff0c;我更想嘗試逆風…

PostgreSQL空值的判斷

PostgreSQL空值的判斷 空值判斷非空判斷總結 空值判斷 -- 查詢為空的 is null,sql簡寫isnull select * from employees where manager_id isnull;select * from employees where manager_id is null;非空判斷 -- 查詢不為空的 is not null;sql簡寫notnull select * from empl…

Java【數據結構】二分查找

&#x1f31e; 題目&#xff1a; &#x1f30f;在有序數組A中&#xff0c;查找目標值target &#x1f30f;如果找到返回索引 &#x1f30f;如果找不到返回-1 算法描述解釋前提給定一個內含n個元素的有序數組A&#xff0c;滿足A0<A1<A2<<An-1,一個待查值target1設…

mysql 8.0安裝

操作系統&#xff1a;22.04.1-Ubuntu apt 安裝命令 sudo apt install mysql-client-core-8.0 sudo apt install mysql-server-8.0終端輸入 mysql 可以直接免密登錄 如果此時提示需要密碼&#xff0c;則可以進入配置文件&#xff0c;設置免密登錄 sudo vim /etc/mysql/mysq…

【探索Linux】—— 強大的命令行工具 P.5(yum工具、git 命令行提交代碼)

閱讀導航 前言一、軟件包管理器 yum1.yum的概念yum的基本指令使用例子 二、git 命令行提交代碼總結溫馨提示 前言 前面我們講了C語言的基礎知識&#xff0c;也了解了一些數據結構&#xff0c;并且講了有關C的一些知識&#xff0c;也學習了一些Linux的基本操作&#xff0c;也了…

第3章 CPU微架構

3.1 指令集架構 指令集ISA是軟件用來與硬件通信的詞匯集合&#xff0c;定義了軟件和硬件之間的通信協議。Intel x86、ARM v8、RISC-V是當今廣泛使用指令集架構的實例。ISA開發者通常要確保符合規范的軟件或固件能在使用該規范構建的任何處理器上執行。廣泛部署的ISA組織通常還…

20W IP網絡吸頂喇叭 POE供電吸頂喇叭

SV-29852T 20W IP網絡吸頂喇叭產品簡介 產品用途&#xff1a; ◆室內豪華型吸頂喇叭一體化網絡音頻解碼揚聲器&#xff0c;用于廣播分區音頻解碼、聲音還原作用 ◆應用場地如火車站、地鐵、教堂、工廠、倉庫、公園停車場等&#xff1b;室內使用效果均佳。 產品特點&#xff…

vue-router中的一些 API

在Vue.js的vue-router中&#xff0c;一些重要api 1、RouterHistory&#xff1a;這是 vue-router 提供的路由歷史記錄對象。它可以跟蹤當前頁面的路由歷史&#xff0c;并提供一些方法和屬性來管理導航和歷史記錄。在 vue-router 中&#xff0c;有兩種類型的路由歷史記錄對象&…

pytorch_lightning報錯 You requested gpu: [1],But your machine only has: [0]

pytorch_lightning報錯 You requested gpu: [1]&#xff0c;But your machine only has: [0] 問題及分析 報錯圖片如下&#xff1a; 分析 gpu:[1]指代的gpu的標號&#xff0c;如果筆記本中只包含一個GPU&#xff0c;一般序號為[0].所以無法找到程序指定的GPU。 解決方法 …

機器學習之邏輯回歸

import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression # 獲得數據 names[Sample code number,Clump Thickness,Uniformity…

編程語言學習筆記-架構師和工程師的區別,PHP架構師之路

&#x1f3c6;作者簡介&#xff0c;黑夜開發者&#xff0c;全棧領域新星創作者?&#xff0c;CSDN博客專家&#xff0c;阿里云社區專家博主&#xff0c;2023年6月CSDN上海賽道top4。 &#x1f3c6;數年電商行業從業經驗&#xff0c;歷任核心研發工程師&#xff0c;項目技術負責…

Egg.js構建一個stream流式接口服務

經常需要用到 stream 流式接口服務,比如&#xff1a;大文件下載、日志實時輸出等等。本文將介紹如何使用Egg.js構建一個 stream 流式接口服務。 一、準備工作 目錄結構&#xff1a; app//controllerindex.jstest.txttest.shindex.js 控制器test.txt 測試文件&#xff0c;最好…

5G+AI數字化智能工廠建設解決方案PPT

導讀&#xff1a;原文《5GAI數字化智能工廠建設解決方案》&#xff08;獲取來源見文尾&#xff09;&#xff0c;本文精選其中精華及架構部分&#xff0c;邏輯清晰、內容完整&#xff0c;為快速形成售前方案提供參考。數字化智能工廠定義 智能基礎架構協同框架 - 端、邊、云、網…

激光雷達 01 線數

一、線數 對于 360 旋轉式和一維轉鏡式架構的激光雷達來說&#xff0c;有幾組激光收發模塊&#xff0c;垂直方向上就有幾條線&#xff0c;被稱為線數。這種情況下&#xff0c;線數就等同于激光雷達內部激光器的數量[參考]。 通俗來講&#xff0c;線數越高&#xff0c;激光器的…

npm run xxx 的時候發生了什么?(以npm run dev舉例說明)

文章目錄 一、去package.json尋找scripts對應的命令二、去node_modules尋找vue-cli-service三、從package-lock.json獲取.bin的軟鏈接1. bin目錄下的那些軟連接存在于項目最外層的package-lock.json文件中。2.vue-cli-service文件的作用3.npm install 的作用 總結 一、去packag…