日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【Qt】2D绘图之窗口-视口转换

發(fā)布時(shí)間:2024/4/24 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Qt】2D绘图之窗口-视口转换 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

00. 目錄

文章目錄

    • 00. 目錄
    • 01. 概述
    • 02. 開發(fā)環(huán)境
    • 03. 程序示例
    • 04. 為什么要修改這個(gè)邏輯坐標(biāo)矩形?
    • 05. 窗口和視口
    • 06. 附錄

01. 概述

在使用QPainter進(jìn)行繪制時(shí),會(huì)使用邏輯坐標(biāo)進(jìn)行繪制,然后再轉(zhuǎn)換為繪圖設(shè)備的物理坐標(biāo)。邏輯坐標(biāo)到物理坐標(biāo)的映射由QPainter的worldTransform()函數(shù)和QPainter的viewport()以及window()函數(shù)進(jìn)行處理。其中視口(viewport)表示物理坐標(biāo)下指定的一個(gè)任意矩形,而窗口(window,與以前講的窗口部件的概念不同)表示邏輯坐標(biāo)下的相同的矩形。默認(rèn)的,邏輯坐標(biāo)和物理坐標(biāo)是重合的,它們都相當(dāng)于繪圖設(shè)備上的矩形。

使用窗口—視口轉(zhuǎn)換可以使邏輯坐標(biāo)系統(tǒng)適合應(yīng)用的要求,這個(gè)機(jī)制也可以用來(lái)讓繪圖代碼獨(dú)立于繪圖設(shè)備。

02. 開發(fā)環(huán)境

Windows系統(tǒng):Windows10

Qt版本:Qt5.15或者Qt6

03. 程序示例

3.1 創(chuàng)建一個(gè)Widget窗口應(yīng)用(其默認(rèn)寬400像素,高300像素,左上角為原點(diǎn))。首先正常繪制一個(gè)正方形

void Widget::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setPen(Qt::blue);painter.drawRect(0, 0, 100, 100);}

的繪圖設(shè)備就是Widget,其左上角就是原點(diǎn)(0, 0)點(diǎn)。效果如下圖所示。

3.2 使用setWindow來(lái)設(shè)置邏輯坐標(biāo)矩形

void Widget::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setPen(Qt::blue);painter.drawRect(0, 0, 100, 100);//設(shè)置邏輯坐標(biāo)painter.setWindow(-50, -50, 100, 100);painter.setPen(Qt::red);painter.drawRect(0, 0, 100, 100); }

運(yùn)行結(jié)果:

現(xiàn)在來(lái)說(shuō)p.setWindow(-50, -50, 100, 100)的作用,它將邏輯坐標(biāo)矩形(后面提到的術(shù)語(yǔ)window窗口)與我們現(xiàn)在的設(shè)備物理坐標(biāo)矩形(后面提到的術(shù)語(yǔ)viewport視口)進(jìn)行了線性映射,這里所說(shuō)的設(shè)備物理坐標(biāo)矩形就是我們可見的Widget的坐標(biāo),就是左上角為(0, 0)點(diǎn),寬400,高300這樣的矩形,線性映射的示意圖如下:

也就是說(shuō),調(diào)用p.setWindow(-50, -50, 100, 100)之后,再次使用p進(jìn)行繪制,那么坐標(biāo)原點(diǎn)就不再是Widget的左上角了,而是到了其中心,以前繪制的寬100、高100的正方形,現(xiàn)在也會(huì)按比例變?yōu)閷?00, 高300,也就是我們看到的這個(gè)紅色矩形。

再來(lái)修改代碼

void Widget::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setPen(Qt::blue);painter.drawRect(0, 0, 100, 100);//設(shè)置邏輯坐標(biāo)painter.setWindow(-50, -50, 100, 100);painter.setPen(Qt::red);painter.drawRect(0, 0, 20, 20); }

運(yùn)行效果如下圖所示

我們將繪制的紅色矩形變小,可以明顯看到,本應(yīng)該是個(gè)正方形,現(xiàn)在卻變成了長(zhǎng)方形。就是因?yàn)樯厦嬲f(shuō)的比例變換造成的,那么怎么才能讓它顯示應(yīng)有的形狀呢,我們來(lái)設(shè)置視口:

void Widget::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setPen(Qt::blue);painter.drawRect(0, 0, 100, 100);//設(shè)置邏輯坐標(biāo)int side = qMin(width(), height());painter.setViewport((width() - side) / 2, (height() - side) / 2, side, side);painter.setWindow(-50, -50, 100, 100);painter.setPen(Qt::red);painter.drawRect(0, 0, 20, 20); }

現(xiàn)在使用setViewport設(shè)置視口為一個(gè)正方形,就是Widget可是區(qū)域上最大的正方形,這樣邏輯坐標(biāo)和物理坐標(biāo)進(jìn)行比例變換的時(shí)候,紅色矩形的寬和高就不會(huì)因?yàn)榭s放的比例不同而發(fā)生變形了,如下圖所示。

04. 為什么要修改這個(gè)邏輯坐標(biāo)矩形?

這是為了便于我們繪圖,因?yàn)槲覀円话憷L圖時(shí)只是想在標(biāo)準(zhǔn)的坐標(biāo)系中應(yīng)該繪制成什么樣子,不會(huì)考慮不同繪圖設(shè)備的具體坐標(biāo)系(比如有的設(shè)備坐標(biāo)原點(diǎn)在其左上角,有的在中心等等),也不會(huì)考慮窗口的大小不同而使用不同的代碼(比如我們只想在一個(gè)寬100、高100的繪圖區(qū)域的中心繪制一個(gè)高20、寬20的正方形,到底實(shí)際繪圖設(shè)備的單位是像素、還是英寸、還是厘米,我們不用考慮)。

05. 窗口和視口

這里說(shuō)的我們想象中的寬100、高100、原點(diǎn)在中心的繪圖區(qū)域,就是邏輯坐標(biāo)下的矩形,也就是使用setWindow設(shè)置的所謂的窗口(英文為Window,注意與窗口部件的窗口二字意義不同);而實(shí)際的繪圖設(shè)備,比如這里的Widget部件,其可視化的區(qū)域上設(shè)置的一個(gè)矩形被稱為視口(英文為viewport),默認(rèn)就是可視化區(qū)域的大小,但是可以通過(guò)setViewport來(lái)設(shè)置。窗口與視口相對(duì)應(yīng),可以進(jìn)行線性變換,這樣,我們就可以通過(guò)先設(shè)置視口,再設(shè)置對(duì)應(yīng)的窗口的方法,來(lái)確保我們的代碼在標(biāo)準(zhǔn)的想象中的坐標(biāo)系中繪制的圖形,可以準(zhǔn)確地顯示在不同的繪圖設(shè)備界面上。

06. 附錄

Qt幫助文檔關(guān)鍵字:Window-Viewport Conversion

源碼下載:【Qt】2D繪圖之窗口-視口轉(zhuǎn)換.rar

總結(jié)

以上是生活随笔為你收集整理的【Qt】2D绘图之窗口-视口转换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。