QT學習教程(二十五)

雙緩沖技術(Double Buffering)( 2、公有函數實現)

#include <QtGui> 
#include <cmath> 
using namespace std; 
#include "plotter.h"

以上代碼為文件的開頭,在這里把std 的名空間加入到當前的全局命名空間。這樣在使用<cmath>里的函數時,就不用前綴 std::了,如可以直接使用函數 floor(),而不用寫成 std::floor()。


Plotter::Plotter(QWidget *parent) : QWidget(parent)
{
setBackgroundRole(QPalette::Dark); setAutoFillBackground(true); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setFocusPolicy(Qt::StrongFocus);
rubberBandIsShown = false;zoomInButton = new QToolButton(this);
zoomInButton->setIcon(QIcon(":/images/zoomin.png")); zoomInButton->adjustSize();
connect(zoomInButton, SIGNAL(clicked()), this, SLOT(zoomIn()));zoomOutButton = new QToolButton(this);
zoomOutButton->setIcon(QIcon(":/images/zoomout.png")); zoomOutButton->adjustSize();
connect(zoomOutButton, SIGNAL(clicked()), this, SLOT(zoomOut()));setPlotSettings(PlotSettings());
}

在構造函數中,調用setBackGroundRole(QPalette::Dark),當對控件進行放大需要重新繪制時,提供給Qt 一個缺省的顏色填充新的區域,為了能夠使用這個機制,還調用了 setAutoFillBackground(true)。函數setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)讓控件在水平和垂直兩個方向上都可以進行伸縮。如果控件需要占據屏幕上很大的控件,經常設置這個屬性。缺省的設置是兩個方向都是 QSizePolicy::Preferred,意思是控件的實際尺寸和它的 sizeHint一致,控件最小只能縮小到它的最小的 sizeHint,并能夠無限放大。

調用setFocusPolicy(Qt::StrongFocus)可以使控件通過鼠標點擊或者Tab 得到焦點。當 Plotter 控件得到焦點時,它可以接受鍵盤敲擊事件。Plotter 控件能夠理解一些鍵盤事件,如+放大,-為縮小,可以向上下左右平移。

在構造函數中,我們還創建了兩個QToolButton,每一個按鈕都有一個圖標。點擊這些圖標可以放大或者縮小顯示的圖像。圖標保存在資源文件中,為了任何程序都可以使用 Plotter 控件,需要在.pro 添加資源條目:

RESOURCES????? = plotter.qrc

資源文件是一個XML 格式的文本文件,和在Spreadsheet 中使用的很像:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>images/zoomin.png</file>
<file>images/zoomout.png</file>
</qresource>
</RCC>

調用QToolButton::adjustSize()調整按鈕的大小為它們的sizeHint。在這里按鈕不在布局中 ,在控件大小改變的時候,又程序計算它們的位置。由于沒有了布局管理,因為我們必須在按鈕的構造函數中確定按鈕的父控件。調用setPlotSettings()函數用來完成控件的初始化。函數代碼如下:

void Plotter::setPlotSettings(const PlotSettings &settings)
{
zoomStack.clear(); zoomStack.append(settings); curZoom = 0;
zoomInButton->hide(); zoomOutButton->hide();refreshPixmap();
}

函數setPlotSettings()確定顯示控件時的PlotSettings。它在Plotter 構造函數中調用,也可以被Plotter 的用戶調用。開始的時候,Plotter 使用的是缺省的放縮值。用戶進行放大一次,就有一個新的PlotSettings 對象加入到堆棧中。這個堆棧中有兩個變量:

zoomStack 是保存PlotSettings 對象的一個數組;

curZoom 是當前使用的 PlotSettings 的一個索引值。

調用setPlotSettings()后,zoomStack 中只有一項,zoomIn 和zoomOut 按鈕隱藏。如果我們調用函數zoomIn()和zoomOut(),這兩個函數中調用了按鈕的show()函數,它們才能顯示出來。(通常,調用父控件的 show()函數就顯示所有的子控件。但是如果我們顯式調用了子控件的hide(),必須要顯示調用其show()函數顯示它,否則就會一直隱藏)

調用refreshPixmap()來更新顯示。通常,我們調用 update()就可以,這里有些不一樣,因為我們要保持QPixmap 一直最新的狀態。更新了圖片后,refreshPixmap()再調用update()把圖片顯示到控件上。

void Plotter::zoomOut()
{
if (curZoom > 0) {
--curZoom;
zoomOutButton->setEnabled(curZoom > 0); zoomInButton->setEnabled(true); zoomInButton->show();
refreshPixmap();
}
}

如果圖片放大了,調用 zoomOut()縮小它。它縮小比例系數,如果還能進一步縮小,zoomOut

按鈕一直有效。顯示zoomIn 按鈕使之按鈕有效,調用refreshPixmap()刷新控件。

void Plotter::zoomIn()
{
if (curZoom < zoomStack.count() - 1) {
++curZoom;
zoomInButton->setEnabled(curZoom < zoomStack.count() - 1); zoomOutButton->setEnabled(true);
zoomOutButton->show(); refreshPixmap();
}
}

如果用戶放大后又縮小控件,下一個放縮系數的 PlotSettings 就進入zoomStack。我們就可以再放大控件。函數zoomIn 增加放縮系數,zoomIn 按鈕顯示出來,只要能夠放大,按鈕會一直有效。同事顯示zoomOut 按鈕使之有效狀態。

void Plotter::setCurveData(int id, const QVector<QPointF> &data)
{
curveMap[id] = data; refreshPixmap();}

函數setCurveData()設置一個指定id 的曲線數據。如果曲線中有一個同樣的 id,那么就用新的數據替代舊數據。如果沒有指定的id,則增加一個新的曲線。曲線的數據類型為QMap<int, QVector<QPointF> >

void Plotter::clearCurve(int id)
{
curveMap.remove(id); refreshPixmap();
}

函數clearCurve()刪除一個指定id 的曲線。

QSize Plotter::minimumSizeHint() const
{
return QSize(6 * Margin, 4 * Margin);
}

函數minimumSizeHint()和sizeHint()很像,確定控件的理想的尺寸。minimumSizeHint()

確定控件的最大尺寸。布局管理器排列控件時不會超過控件的最大尺寸。由于Margin 值為 50,所以我們返回的值為 300×200,包括四個邊界的寬度和 Plot 本身。如果再小,尺寸太小Plot 就不能正常顯示了。

QSize Plotter::sizeHint() const
{
return QSize(12 * Margin, 8 * Margin);
}

在sizeHint()中,我們返回控件的理想尺寸,用 Margin 常數作為倍數,長寬的比例為 3:2,與minimumSizeHint()中比例一致。

以上是Plotter 的公有函數和槽函數。

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

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

相關文章

設計模式筆記_結構型_裝飾器模式

1.裝飾器模式介紹裝飾器模式是一種結構型設計模式&#xff0c;允許你動態地給對象添加行為&#xff0c;而無需修改其代碼。它的核心思想是將對象放入一個“包裝器”中&#xff0c;這個包裝器提供了額外的功能&#xff0c;同時保持原有對象的接口不變。想象一下&#xff0c;你有…

day25 力扣90.子集II 力扣46.全排列 力扣47.全排列 II

子集II給你一個整數數組 nums &#xff0c;找出并返回所有該數組中不同的遞增子序列&#xff0c;遞增子序列中 至少有兩個元素 。你可以按 任意順序 返回答案。數組中可能含有重復元素&#xff0c;如出現兩個整數相等&#xff0c;也可以視作遞增序列的一種特殊情況。示例 1&…

Solidity 中的`bytes`

在 Solidity 中&#xff0c;bytes 和 bytes32 都是用來保存二進制數據的類型&#xff0c;但它們的長度、使用場景、Gas 成本完全不同。? 一句話區分類型一句話總結bytes32定長 32 字節&#xff0c;適合做哈希、地址、標識符等固定長度數據。bytes動態長度字節數組&#xff0c;…

初學者STM32—PWM驅動電機與舵機

一、簡介 上一節課主要學習了輸出比較和PWM的基本原理和結構&#xff0c;本節課就主要以實踐為主通過STM32最小系統板和驅動器控制舵機和直流電機。 上一節課的坐標 初學者STM32—輸出比較與PWM-CSDN博客 二、舵機 舵機是一種根據輸入PWM信號占空比來控制輸出角度的裝置 輸…

C++中的異常處理機制:try-catch

一、基本概念 異常&#xff08;Exception&#xff09;&#xff1a;程序執行過程中發生的非正常情況&#xff0c;比如除以零、訪問越界、內存不足等。 異常處理&#xff08;Exception Handling&#xff09;&#xff1a;對異常情況進行捕獲、分析&#xff0c;并采取補救措施&…

如何從 Windows 11 或 10 遠程訪問 Ubuntu 24.04 或 22.04 桌面

了解如何使用 RDP(遠程桌面協議)從 Windows 11 或 10 遠程連接 Ubuntu 24.04 Noble 或 22.04 LTS Jammy JellyFish 桌面的步驟。 Windows 提供了一個便捷的功能,稱為遠程桌面連接,它使用 RDP 協議來遠程連接 PC。當從 Windows 系統建立遠程桌面連接時,使用起來非常簡單,…

Linux 服務器中,Tab 鍵自動補全功能失效

在 Linux 服務器中&#xff0c;Tab 鍵自動補全功能失效通常與 bash-completion 組件缺失或配置異常有關。以下是解決問題的兩個關鍵 YUM 指令及操作步驟&#xff1a;1. 安裝 bash-completion 組件 sudo yum install -y bash-completion說明&#xff1a; bash-completion 是提供…

SpringBoot服裝推薦系統實戰

Spring Boot 服裝推薦系統實例 以下是基于Spring Boot實現的服裝推薦系統的30個實例代碼示例,涵蓋核心功能和實現方法。 用戶注冊與登錄功能 @RestController @RequestMapping("/api/auth") public class AuthController {@Autowiredprivate UserService userSer…

WIN10系統優化篇(一)

你是否疑惑為什么別人家的電腦運行速度飛快&#xff0c;而自己的卻卡頓難用&#xff1f;其實&#xff0c;很多時候 Windows 系統可以通過簡單的優化措施來提升使用體驗。本文根據項目實戰多年對 Win10 優化經驗&#xff0c;將幫你找出系統卡頓的原因&#xff0c;并給出針對性的…

Flutter狀態管理篇之ChangeNotifier基礎篇(一)

目錄 前言 一、什么是ChangeNotifier 二、ChangeNotifier 的基本用法 三、結合Flutter UI 使用 四、結合 Provider 的高級用法 五、ChangeNotifier 的優勢與注意事項 5.1 優勢 5.2 注意事項 六、與 ValueNotifier 的比較 七、實際應用場景 八、總結 前言 在 Flutter…

react17更新哪些新特性

React 17 是一個“無新特性”的發布版本&#xff0c;它的主要目標是為未來的 React 版本打好基礎&#xff0c;同時改善與舊版本共存和升級的體驗。雖然沒有引入新的開發者 API&#xff0c;但它在內部做了很多重要的改進。以下是 React 17 的核心更新內容和特性&#xff1a;&…

Unity 常見數據結構分析與實戰展示 C#

Unity 常見數據結構分析與實戰展示 提示&#xff1a;內容純個人編寫&#xff0c;歡迎評論點贊&#xff0c;來指正我。 文章目錄Unity 常見數據結構分析與實戰展示1. 引言2. Unity 數據結構概述3. 常見數據結構1. 數組&#xff08;Array&#xff09;2. 列表&#xff08;List&…

【Linux網絡編程】應用層協議 - HTTP

目錄 初識HTTP協議 認識URL HTTP協議的宏觀格式 Socket封裝 TcpServer HttpServer 整體設計 接收請求 web根目錄與默認首頁 發送應答 完善頁面 HTTP常見Header HTTP狀態碼 HTTP請求方法 cookie與session Connection 抓包 初識HTTP協議 應用層協議一定是基于…

技術演進中的開發沉思-36 MFC系列: 對話框

MFC這個章節里&#xff0c;不能忽視的是對話框的開發。如果把 MFC 程序比作一棟辦公樓&#xff0c;那對話框就是「會客室」—— 它是程序與用戶面對面交流的地方&#xff1a;用戶在這里輸入數據&#xff0c;程序在這里展示信息&#xff0c;彼此的互動都從這個空間開始。今天圍繞…

(李宏毅)deep learning(五)--learning rate

一&#xff0c;關于learning rate的討論&#xff1a;&#xff08;1&#xff09;在梯度下降的過程中&#xff0c;當我們發現loss的值很小的時候&#xff0c;這時我們可能以為gradident已經到了local min0&#xff08;低谷&#xff09;,但是很多時候&#xff0c;loss很小并不是因…

pytorch:tensorboard和transforms學習

tensorboard:可視化數據 在anaconda安裝&#xff1a; pip install tensorboard2.12.0最好使用這個版本 不然后面調用會報錯 因為版本過高的原因 然后還碰到了安裝的時候 安裝到C盤去了 但是我用的虛擬環境是在E盤&#xff1a;此時去C盤把那些新安裝的復制過來就好了 附錄我C盤的…

常用的100個opencv函數

以下是OpenCV中最常用的100個函數及其作用與注意事項的全面整理&#xff0c;按功能模塊分類&#xff0c;結合官方文檔與工業實踐優化排序。各函數均標注Python&#xff08;cv2&#xff09;和C&#xff08;cv::&#xff09;命名&#xff0c;重點參數以加粗突出&#xff1a; &…

【C++】紅黑樹,詳解其規則與插入操作

各位大佬好&#xff0c;我是落羽&#xff01;一個堅持不斷學習進步的大學生。 如果您覺得我的文章有所幫助&#xff0c;歡迎多多互三分享交流&#xff0c;一起學習進步&#xff01; 也歡迎關注我的blog主頁: 落羽的落羽 一、紅黑樹的概念與規則 紅黑樹是一種更加特殊的平衡二…

Camera相機人臉識別系列專題分析之十七:人臉特征檢測FFD算法之libhci_face_camera_api.so 296點位人臉識別檢測流程詳解

【關注我,后續持續新增專題博文,謝謝!!!】 上一篇我們講了: 這一篇我們開始講: Camera相機人臉識別系列專題分析之十七:人臉特征檢測FFD算法之libhci_face_camera_api.so 296點位人臉識別檢測流程詳解 目錄 一、背景 二、:FFD算法libhci_face_camera_api.s…

PostgreSQL 16 Administration Cookbook 讀書筆記:第7章 Database Administration

編寫一個要么完全成功要么完全失敗的腳本 事務&#xff08;transaction&#xff09;可以實現all or nothing。不過這里指的是psql的-和--single-transaction選項。可以實現transaction wrapper&#xff1a; 此選項只能與一個或多個 -c 和/或 -f 選項組合使用。它會導致 psql 在…