Qt的坐標系系統 - 3個坐標系,2個變換

參考:

  1. https://zhuanlan.zhihu.com/p/584048811
  2. https://www.zhihu.com/tardis/zm/art/634951149?source_id=1005

小談Qt的坐標系系統

Qt中有三個坐標系

  • 設備坐標系
  • 窗口坐標系
  • 邏輯坐標系

設備坐標系: 即Device坐標系。也是物理坐標系。即真實的的物理坐標系。

邏輯坐標系: 即用戶坐標系。也就是說日常大家使用Qt的時候的坐標系。

窗口坐標系: 這個坐標系是QPainter設置setWindow以后的一個坐標系。

這三個坐標系,基本上就代表了常規的繪制引擎的三個坐標系。

那么三個坐標系,就代表可以用兩次變換來實現了。

這個就是QPainter中的setWindow() & setViewport()的兩個概念了

直接看下圖

在這里插入圖片描述在這里插入圖片描述via https://doc.qt.io/qt-6/coordsys.html#window-viewport-conversion

OK,既然有了這些概念,那么我們就開始講一下,坐標系的轉換流程。

廢話不多說
還是按照我的方式 & Qt的官方文檔來講吧

我自己的例子

畫個圖,描述下這三個坐標系

在這里插入圖片描述平時我們的三個坐標系都是相同的,都是水平方向是X軸,垂直方向是Y軸,坐標原點是左上角(0, 0)。

X軸從左到右增加,Y軸從上到下增加

即如圖所示
在這里插入圖片描述那么三個坐標系的變化流程就是

在這里插入圖片描述還是先上個Qt的Demo

Qt的Demo

設定,屏幕的DPI是96

三個坐標系重疊

先創建一個QWidget,然后設置其大小是(500, 500)

resize(500,500);

然后再重寫他的PaintEvent事件

void QtWidgetsApplication1::paintEvent(QPaintEvent*e)
{
QPainter painter(this);
painter.drawLine(0,0,500,500);
}

那么表現
在這里插入圖片描述這里可以先重點說下
我們以普通用戶(程序員)的角度來理解這個代碼。因為有三個坐標系,所以Qt的代碼全都是以邏輯坐標系為基礎的。對于這個代碼來講

painter.drawLine(0,0,500,500);

drawLine的時候實際上就是以邏輯坐標系為準。這時候,三個坐標系是相等的,沒有任何比例變化。大家可以理解為這三個坐標系是重疊的。

setWindow()
控制變量,其他的代碼不變,我們只單獨設置setWindow這個代碼setWindow的作用,就是在物理坐標系不變的情況下,將邏輯坐標系進行縮放。

假定,我們的代碼是這樣的。將邏輯坐標擴大一倍,那么代碼就是這樣的

void QtWidgetsApplication1::paintEvent(QPaintEvent*e)
{
QPainter painter(this);
painter.setWindow(0,0,1000,1000);
painter.drawLine(0,0,500,500);
}

這時候我們的窗口就變成了這個樣子。
在這里插入圖片描述也就是說,我的物理大小,并沒有變,我通過更改邏輯坐標,(放大兩倍的效果) 看起來將我的整個坐標系變大了。比如原來我可以通過

painter.drawLine(0,0,500,500);

來繪制對角。

經過

painter.setWindow(0,0,1000,1000)\\放大邏輯坐標系兩倍

最后

painter.drawLine(0,0,500,500);\\只能繪制一半的效果。

在這里插入圖片描述如果還想繪制對角,那么就得

painter.drawLine(0,0,1000,1000);

在這里插入圖片描述也就是,我們現在將用戶的坐標系放大了兩倍。這個就是setWindow的作用。

setViewport()
大家可以理解setViewport的作用就是控制物理坐標系的。
在這里插入圖片描述比如官方代碼

int side=qMin(width(),height());
int x=(width()-side/2);
int y=(height()-side/2);painter.setViewport(x,y,side,side); 

還要控制窗口的寬高,這時候就更難理解了。我的例子還是控制變量,假定Window不變。我們只更改ViewPort

還是那個例子,窗口大小(500, 500)。我們還是畫對角線。這時候我們把代碼改成

void QtWidgetsApplication1::paintEvent(QPaintEvent*e)
{
QPainter painter(this);
painter.setViewport(0,0,1000,1000)
painter.drawLine(0,0,250,250);
}

大家可以看現象,畫線也變粗了。這是為啥呢?
在這里插入圖片描述很簡單,painter.setViewport(0, 0, 1000, 1000)這個代碼相當于把整個物理坐標系翻倍了。也就是單位邏輯坐標變大了。

原來邏輯坐標畫1個像素點,現在相當于畫2個。

所以會有兩個現象

  • 畫線變粗
  • drawLine現在只需要一半就可以撐滿整個窗口。

小結:

在這里插入圖片描述還是要好好觀察下這個順序。

Qt通過三個坐標系,來做到了窗口之間的變換 & 放大縮小。

那么工程上是如何使用的呢。一般來說viewport這個跟當前物理DPI保持一致。

然后通過setWindow放大坐標系

如果你想把整個邏輯坐標系放大。那么就用setWindow()還是看你當前的邏輯需求- 即邏輯坐標系的需求。

以這個為出發點,那么再去理解setWindow & setViewport就很好理解了。

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

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

相關文章

給鼠標描述符打上注釋防止忘記

static uint8_t g_mouse_hid_desc[] { //通用桌面設備 0x05, 0x01, // USAGE_PAGE (Generic Desktop) //鼠標設備 0x09, 0x02, // USAGE (Mouse) //應用集合 0xa1, 0x01, // COLLECTION (Application) //指針設備 0x09, 0x01, // USAGE (Pointer) //物理集合 0xa1, 0x00, // C…

【Linux】free命令使用

free命令 ?free是指查看當前系統內存的使用情況,它顯示系統中剩余及已用的物理內存和交換內存,以及共享內存和被核心使用的緩沖區。 作者 作者:Brian Edmonds。 語法 free [參數] free 命令 -Linux手冊頁 命令選項及作用 執行令 &am…

【二分查找】【滑動窗口】LeeCode2528:最大化城市的最小電量

作者推薦 【動態規劃】【廣度優先】LeetCode2258:逃離火災 本文涉及的基礎知識點 二分查找算法合集 滑動窗口 題目 給你一個下標從 0 開始長度為 n 的整數數組 stations ,其中 stations[i] 表示第 i 座城市的供電站數目。 每個供電站可以在一定 范圍 內給所有城…

Java學習總結

1. Java集合體系框架 java.util中包含 Java 最常用的the collections framework。 Java集合類主要由兩個根接口Collection和Map派生出來的。 Collection 接口派生出了三個子接口List、Set、Queue。Map 接口 因此Java集合大致也可分成List、Set、Queue、Map四種接口體系。 …

CDH6.3.2安裝

文章目錄 [toc]一、CM簡介1、ClouderaManager的概念2、ClouderaManager的功能3、ClouderaManager的架構 二、準備清單1、部署步驟2、集群規劃3、軟件環境準備 三、安裝清單1、操作系統iso包2、JDK包3、MySQL包4、CM和CDH包5、部署ansible 四、基礎環境準備1、配置網絡2、配置ho…

Java項目開發,業務比較復雜如何減少bug

Java項目開發,業務比較復雜如何減少bug 當Java開發工作涉及復雜業務時,可以采取以下方法來減少bug的數量: 1、深入了解業務需求 充分了解業務需求,與業務人員進行充分的溝通和交流,確保對需求的理解正確。在需求分析…

el-collapse 默認展開第一個(實測有效)

<el-collapse accordion v-model"activeCollapse"> <el-collapse-item v-for"(item, index) in assetList" :name"index" :key"item.id" > 我這個是通過循環, 只需要v-model 綁定的值和 name 相等,就可以實現展開 然后就…

重新認識Word——給圖、表、公式等自動編號

重新認識Word——給圖、表、公式等自動編號 給圖增加題注題注失敗的情況給圖添加“如圖xx-xx所示” 給公式插入題注第一步——先加題注第二步——設置兩個制表符 解決題注“圖一-1”的問題 前面我們已經學習了如何引用多級列表自動編號了&#xff0c;現在我們有第二個問題&…

大數據湖體系規劃與建設方案:PPT全文51頁,附下載

關鍵詞&#xff1a;大數據解決方案&#xff0c;數據湖解決方案&#xff0c;數據數倉建設方案&#xff0c;大數據湖建設規劃&#xff0c;大數據湖發展趨勢 一、大數據湖體系規劃與建設背景 在傳統的企業信息化建設中&#xff0c;各個業務系統通常是獨立建設的&#xff0c;導致…

學習筆記10——Mysql的DDL語句

學習筆記系列開頭慣例發布一些尋親消息 鏈接&#xff1a;https://baobeihuijia.com/bbhj/contents/3/197161.html 數據庫創建&#xff1a; CREATE DATABASE books&#xff1b; CREATE DATABASE IF NOT EXISTS books;更改字符集 ALTER DATABASE books CHARACTER SET gbk;庫的刪…

FFmpeg之AVFilterLink

這個結構體主要是用來link兩個filter的,它存在于每個AVFilterContext中 struct AVFilterContext {const AVClass *av_class; ///< needed for av_log() and filters common optionsconst AVFilter *filter; ///< the AVFilter of which this is an inst…

XX.push is not a function

錯誤通常發生在嘗試在非數組類型的變量上使用push方法 問題&#xff1a;定義了數組類型&#xff0c;用push方法一直報錯&#xff0c;感覺哪里都沒毛病 原因&#xff1a;雖然剛開始定義了數組類型&#xff0c;但可能是因為在代碼的某個地方將其重新賦值為了非數組類型的值。 …

【計算機網絡基礎2】IP地址和子網掩碼

1、IP地址 網絡地址 IP地址由網絡號&#xff08;包括子網號&#xff09;和主機號組成&#xff0c;網絡地址的主機號為全0&#xff0c;網絡地址代表著整個網絡。 廣播地址 廣播地址通常稱為直接廣播地址&#xff0c;是為了區分受限廣播地址。 廣播地址與網絡地址的主機號正…

Mybatis-Plus基礎之框架基礎

文章目錄 Mybatis-Plus 框架基礎引入 maven 依賴定義實體類&#xff0c;并標注注解定義 Mapper 接口&#xff0c;要求繼承自特定父接口使用 MapperScan 注解&#xff0c;掃描 mapper 接口所在位置驗證 Mybatis-Plus 框架基礎 MyBatis-Plus 是 MyBatis 的一種增強框架&#xff…

C語言常用字符串

目錄 1.什么是字符串 2.如何定義字符串 第3和第4定義的區別&#xff1a;3是字符串變量&#xff0c;4是字符串常量&#xff0c;不予許被修改 3.strlen和sizeof的區別 4.地址分配&#xff08;malloc,realloc,free,memset&#xff09; 案例 5.字符串拷貝(strcpy,strncpy) …

kafka創建新topic

創建topic bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic mytopic bin/kafka-topics.sh //bin目錄下的.sh --create --bootstrap-server //固定寫法 localhost:9092 //ip端口 --replication-fac…

vue 集成行政區域選擇插件region和數據回顯

故事&#xff1a;最近&#xff0c;項目需要進行行政區域圍欄的繪制&#xff0c;由于老舊項目是利用js保存全國行政區域地址和編碼&#xff0c;在選擇器select進行匹配顯示&#xff0c;但此方法復雜&#xff0c;因此選擇集成區域插件region 步驟一&#xff1a;用命令安裝region…

JS實現返利網注冊系統(網頁數據驗證)

主代碼 <!DOCTYPE HTMLPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"><head><title>返利網注冊</tit…

品牌線下店鋪的查價方式

不同于電商平臺&#xff0c;線下店鋪會更傳統&#xff0c;產品定價除了受品牌規則的約束&#xff0c;同樣也與門店實際銷量和促銷有關&#xff0c;當遇到地方活動&#xff0c;促銷力度大了&#xff0c;價格難免會與品牌要求相差異&#xff0c;但是管控渠道&#xff0c;包含線上…

無法將“mvn”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫,如果包括路徑,請確保路徑正確,然后再試一次。

這個錯誤表明系統無法找到mvn命令。這通常是因為Maven沒有正確安裝或者Maven的安裝路徑沒有添加到系統的環境變量中。你需要確保Maven已經正確安裝&#xff0c;并且將Maven的安裝路徑添加到系統的環境變量中。 你可以按照以下步驟在Windows上安裝Maven&#xff1a; 1. 訪問Mave…