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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

QT-QPainter绘制曲线等基本图形

發布時間:2023/12/18 c/c++ 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QT-QPainter绘制曲线等基本图形 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Qt中繪制2D圖形最核心的一個類是QPainter。類QPainter是在設備類QPaintDevice上繪制幾何圖形(包括直線、曲線、圓形、弧形、矩形等等),其中設備類QPaintDevice的子類又有QWidget、QImage、QPictrue、QPixmap、QOpenGLPaintDevice等,也即是說,我們可以繼承這些類,通過重寫QPaintEvent事件進行重繪,或者用事件過濾器捕獲QPaintEvent事件信息進行響應重繪也行。

一、原理講解
本文主要總結用類QPainter繪制直線、矩形、圖片。其中,繪制直線用畫筆類QPen,繪制矩形不但用單畫筆類QPen,還要用到畫刷類QBrush,繪制圖片需要用類QPixmap。

QPen:繪制幾何圖形邊緣的線段顏色、線段寬度、線段各種類型(點畫線、虛線、solid實體線段)等等;

QBrush:填充幾何圖形的調色板,由顏色和填充風格組成。

QPixmap:加載圖片資源,一般是較小的圖片。如果圖片很大,可以用QImage,然后通過QPixmap::fromImage(QImage *)進行加載;

1.1繪制直線
繪制直線用到函數QPainter::drawLine(QPoint,QPoint),步驟如下:

a1:先設置畫筆QPen線段顏色、線段寬度、線段類型;

a2:確定繪制直線的起點和終點;

a3:初始化QPainter,設置畫筆QPen,然后調用函數QPainter::drawLine()進行直線繪制;

核心代碼如下:

#include <QPen>
#include <QPoint>
#include <QPaintEvent>
?
void QCustomWidget::paintEvent(QPaintEvent *event)
{
? ? Q_UNUSED(event);
? ? //繪圖前準備畫筆、畫刷
? ? QPen pen; //畫筆。繪制圖形邊線,由顏色、寬度、線風格等參數組成
? ? pen.setColor(QColor(255,0,0,255)); ? ?
? ? QPainter painter(this); ? //可在QPaintDevice上繪制各種圖形。QPaintDevice有之類QWidget、QImage、QOpenGLPaintDevice等
? ? painter.setPen(pen); ? ?
? ? painter.drawLine(QPoint(0,0),QPoint(this->rect().width()-50,0)); ? //QPainter繪制直線
}


1.2繪制矩形
繪制矩形用到核心函數為QPainter::drawRect(),步驟如下:

?

a1:先設置畫筆QPen線段顏色、線段寬度、線段類型,也就是矩形的邊框;

a2:接著確定畫刷QBrush的填充顏色和填充類型;初始化是,要設置填充顏色和填充類型(QBrush::setStyle(Qt::SolidPattern);),否則畫刷填充失敗!!!

a3:確定繪制矩形的起點、終點、寬度、高度;

a3:初始化QPainter,設置畫筆QPen和畫刷QBrush,然后調用函數QPainter::drawRect()繪制矩形;

核心代碼如下:

void QCustomWidget::paintEvent(QPaintEvent *event)
{
? ? Q_UNUSED(event);
? ? //繪圖前準備畫筆、畫刷
? ? QPen pen; //畫筆。繪制圖形邊線,由顏色、寬度、線風格等參數組成
? ? pen.setColor(QColor(255,0,0,255));
? ? QBrush brush; ? //畫刷。填充幾何圖形的調色板,由顏色和填充風格組成
? ? brush.setColor(QColor(0,255,0,120));
? ? brush.setStyle(Qt::SolidPattern);
? ? QPainter painter(this); ? //可在QPaintDevice上繪制各種圖形。QPaintDevice有之類QWidget、QImage、QOpenGLPaintDevice等
? ? painter.setPen(pen);
? ? painter.setBrush(brush);
? ? painter.drawRect(50,50,200,100);
}


1.3繪制圖像
繪制圖像用到核心函數為QPainter::drawPixmap(),步驟如下:

?

a1:實例一個QPixmap對象,然后加載一幅圖片;

a2:調用函數QPainter::drawPixmap()進行圖片繪制;

核心代碼如下:

void QCustomWidget::paintEvent(QPaintEvent *event)
{
? ? Q_UNUSED(event); ?
?
? ? QPainter painter(this); ? //可在QPaintDevice上繪制各種圖形。QPaintDevice有之類QWidget、QImage、QOpenGLPaintDevice等
? ??
? ? //繪制圖片
? ? QPixmap pixmap;
? ? pixmap.load((QString(":/resource/image/向右箭頭.jpg")));
? ? painter.drawPixmap(rect().width()-50,0,50,50,pixmap);
}


二、完整實例代碼工程
該工程是一個完整的實例,功能包括用QPainter繪制直線、繪制和填充矩形、繪制圖片、實時輸出窗口QWIdget大小和最大化時的窗口大小尺寸。其中,所有功能都封裝在繼承QWidget的類QCustomWidget,只要調用QWidget一樣調用類QCustomWidget就行。

?

2.1新建一個類名為QCustomWidget,分別在qcustomwidget.h、qcustomwidget.cpp中添加如下代碼
qcustomwidget.h

#ifndef QCUSTOMWIDGET_H
#define QCUSTOMWIDGET_H
?
#include <QWidget>
?
class QCustomWidget : public QWidget
{
? ? Q_OBJECT
public:
? ? explicit QCustomWidget(QWidget *parent = nullptr);
?
signals:
?
protected:
? ? void paintEvent(QPaintEvent *event);
?
public slots:
};
?
#endif // QCUSTOMWIDGET_H
?

qcustomwidget.cpp

#include "qcustomwidget.h"
?
#include <QPen>
#include <QBrush>
#include <QPoint>
#include <QPixmap>
#include <QPainter>
#include <QDebug>
?
QCustomWidget::QCustomWidget(QWidget *parent) : QWidget(parent)
{
? ? this->resize(960,640);
// ? ?this->setWindowFlag(Qt::FramelessWindowHint); ? //設置無邊框
}
?
void QCustomWidget::paintEvent(QPaintEvent *event)
{
? ? Q_UNUSED(event);
? ? //繪圖前準備畫筆、畫刷
? ? QPen pen; //畫筆。繪制圖形邊線,由顏色、寬度、線風格等參數組成
? ? pen.setColor(QColor(255,0,0,255));
? ? QBrush brush; ? //畫刷。填充幾何圖形的調色板,由顏色和填充風格組成
? ? brush.setColor(QColor(0,255,0,120));
? ? brush.setStyle(Qt::SolidPattern);
? ? QPainter painter(this); ? //可在QPaintDevice上繪制各種圖形。QPaintDevice有之類QWidget、QImage、QOpenGLPaintDevice等
? ? painter.setPen(pen);
? ? painter.setBrush(brush);
? ? painter.drawLine(QPoint(0,0),QPoint(this->rect().width()-50,0)); ? //QPainter繪制直線
? ? painter.drawRect(50,50,200,100);
?
? ? //繪制圖片
? ? QPixmap pixmap;
? ? pixmap.load((QString(":/resource/image/向右箭頭.jpg")));
? ? painter.drawPixmap(rect().width()-50,0,50,50,pixmap);
?
? ? qDebug()<<rand();
}
?

2.2調用代碼如下
QCustomWidget *customWidget=new QCustomWidget;
customWidget->show();
?

2.3程序運行結果圖如下

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?最大化前

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?最大化后

?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 拖拽圖片
?

/************************

使用qt的QPainter可以繪制出任何你想要的圖形,同時也須要一定的功底;下面介紹動態正弦曲線(水波效果)的畫法。

為了更好理解,分4部分去理解如何繪制。先介紹畫一個畫三角形,再介紹畫二個畫三角形,然后畫靜態正弦曲線(水波),最后,畫動態正弦曲線(水波效果)。主要用到QPainter與QPainterPath類。

一、下面介紹一個畫三角形
文件包含如圖零所示

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖零:包含文件

triangle.pro?

?
QT ? ? ? += core gui
?
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
?
TARGET = triangle
TEMPLATE = app
?
?
SOURCES += \
? ? main.cpp \
? ? triangle.cpp
?
HEADERS ?+= \
? ? triangle.h
triangle.h

?
#ifndef TRIANGLE_H
#define TRIANGLE_H
?
#include <QWidget>
#include <QPainter>
#include <QtMath>
#include <QDebug>
?
class Triangle : public QWidget
{
? ? Q_OBJECT
public:
? ? explicit Triangle (QWidget *parent = 0);
?
protected:
? ? void paintEvent(QPaintEvent *event);
private:
?
};
?
#endif // TRIANGLE_H
main.cpp

?
#include "triangle.h"
#include <QApplication>
?
?
int main(int argc, char *argv[])
{
? ? QApplication a(argc, argv);
?
? ? Triangle myTriangle;
? ? myTriangle.show();
?
? ? return a.exec();
}
triangle.cpp

#include "triangle.h"
Triangle::Triangle(QWidget *parent) : QWidget(parent)
{
}
?
void Triangle::paintEvent(QPaintEvent *event)
{
? ?Q_UNUSED(event);
? ?QPainter painter(this); ?//QWidget為繪圖設備,創建一個畫刷對象,主要用到設置顏色和填充模式,brush,setBrush
? ?int width=this->width(); ?//獲取QWidget 窗口的寬度
? ?int height=this->height();//獲取QWidget 窗口的高度
? ?QPainterPath drawtriangle; ?//單獨畫三角形
?
? ?drawtriangle.moveTo(0, height);//左下角,第一點坐標為(0,height);
? ?drawtriangle.lineTo(width/2, width/2);//第二點坐標為(width/2,width/2)
? ?drawtriangle.lineTo(width, height);//右下角,第三坐標(width, height),移動到右下角結束點,整體形成一個閉合路徑
? ?painter.setBrush(Qt::green); ? //填充綠色
? ?painter.drawPath(drawtriangle); ?//繪制出圖形
}
效果如圖一所示?

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖一:triangle

二、畫兩個三角形
修改上述的triangle.cpp文件 為如下代碼

#include "triangle.h"
Triangle::Triangle(QWidget *parent) : QWidget(parent)
{
}
?
void Triangle::paintEvent(QPaintEvent *event)
{
? ?Q_UNUSED(event);
? ?QPainter painter(this); ?//QWidget為繪圖設備,創建一個畫刷對象,主要用到設置顏色和填充模式,brush,setBrush
? ?int width=this->width(); ?//獲取QWidget 窗口的寬度
? ?int height=this->height();//獲取QWidget 窗口的高度
? ?QPainterPath drawtriangle; ?//單獨畫三角形
?
? ?drawtriangle.moveTo(0, height);//左下角,第一點坐標為(0,height);
? ?drawtriangle.lineTo(width/4, height/2);//第二點坐標為(width/4,height/2)
? ?drawtriangle.lineTo(width/2, height);//第三點坐標為(width/2,height)
? ?drawtriangle.lineTo(width*3/4,height/2);//第四點坐標為(width*3/4,height/2)
? ?drawtriangle.lineTo(width, height);//右下角,第五坐標(width, height),移動到右下角結束點,整體形成一個閉合路徑
? ?painter.setBrush(Qt::green); ? //填充綠色
? ?painter.drawPath(drawtriangle); ?//繪制出圖形
}
效果如圖二所示?

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖二:兩個三角形

三、畫靜態正弦曲線(水波)
修改上述的triangle.cpp文件 為如下代碼

#include "triangle.h"
Triangle::Triangle(QWidget *parent) : QWidget(parent)
{
}
?
?
void Triangle::paintEvent(QPaintEvent *event)
{
? ? ?Q_UNUSED(event);
? ? ?QPainter painter(this); ?//QWidget為繪圖設備,創建一個畫刷對象,主要用到設置顏色和填充模式,brush,setBrush
? ? ?int width=this->width(); ?//獲取QWidget 窗口的寬度
? ? ?int height=this->height(); //獲取QWidget 窗口的高度
? ? ?//正弦曲線公式 y = A * sin(ωx + φ) + k
? ? ?double w = M_PI/100; ?//w為角速度 ,可以理解為波浪的密度,越大密度越大
? ? ?double A = 20; ? ?// ?A表示振幅,可以理解為水波的高度,越大高度越高
? ? ?double k = 20; ? ?// ?k表示y軸偏移
?
?
? ? ?QPainterPath wave; //波浪區域
? ? ?wave.moveTo(0, height);//第一點坐標為(0,height);
? ? ?double m_offset = 6; //初相位,初值該值不一樣,獲得waveY也不一樣,可試驗該值為不同值的時候,曲線的起始點的區別 ? ? ? ?//
? ? ?for(int x = 0; x <= width; x+=1) ?//x從0~w的值而改變,從而得到正弦曲線
? ? ?{
? ? ? ? ? double waveY = (double)(A * sin(w * x + m_offset)) + k;// waveY隨著x的值改變而改變,從而得到正弦曲線
? ? ? ? ? wave.lineTo(x, waveY); ? //從上一個繪制點畫一條線到(x,waveY);
? ? ?}
? ? ?wave.lineTo(width, height); //右下角,坐標(width, height),移動到右下角結束點,整體形成一個閉合路徑
? ? ?painter.setBrush(Qt::green); //填充綠色
? ? ?painter.drawPath(wave); ? ? ?//繪制出圖形
}
效果如圖三所示 ?

? ? ? ? ? ? ? ? ? ? ? ?

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖三:正弦曲線(水波) ?

四、畫動態正弦曲線(水波效果)
相對于靜態態正弦曲線,動態正弦曲線產生水波效果主要依靠,初相位的改變與定時器的刷新。基于上面的代碼只需修改“double m_offset = 6;”為“double m_offset += 6”; //初相位改變,增加timerEvent// 定時器事件,定時器的刷新;初相位每次加6,每次曲線的起始點不一樣,加上定時器的刷新,從而產生動態的效果。

修改上述的triangle.h文件 為如下代碼

?
#ifndef TRIANGLE_H
#define TRIANGLE_H
?
#include <QWidget>
#include <QPainter>
#include <QtMath>
#include <QDebug>
?
class Triangle : public QWidget
{
? ? Q_OBJECT
public:
? ? explicit Triangle (QWidget *parent = 0);
?
protected:
? ? void paintEvent(QPaintEvent *event);
? ? void timerEvent(QTimerEvent *event);
private:
? ? double m_offset;
};
?
#endif // TRIANGLE_H
修改上述的triangle.cpp文件 為如下代碼

#include "triangle.h"
Triangle::Triangle(QWidget *parent) : QWidget(parent)
{ ??
? ? ?this->startTimer(80);
}
?
?
void Triangle::paintEvent(QPaintEvent *event)
{
? ? ?Q_UNUSED(event);
?
? ? ?QPainter painter(this); ?//QWidget為繪圖設備,創建一個畫刷對象,主要用到設置顏色和填充模式,brush,setBrush
? ? ?int width=this->width(); ?//獲取QWidget 窗口的寬度
? ? ?int height=this->height(); //獲取QWidget 窗口的高度
? ? ?//正弦曲線公式 y = A * sin(ωx + φ) + k
? ? ?double w = M_PI/100; ?//w為角速度 ,可以理解為波浪的密度,越大密度越大
? ? ?double A = 20; ? ?// ?A表示振幅,可以理解為水波的高度,越大高度越高
? ? ?double k = 20; ? ?// ?k表示y軸偏移
?
?
? ? ?QPainterPath wave; //波浪區域
? ? ?wave.moveTo(0, height);//第一點坐標為(0,height);
? ? ?m_offset += 6; //初相位每次加6,每次曲線的起始點不一樣,加上定時器的刷新,從而產生動態的效果
? ? ?for(int x = 0; x <= width; x+=1) ?//x從0~w的值而改變,從而得到正弦曲線
? ? ?{
? ? ? ? ? double waveY = (double)(A * sin(w * x + m_offset)) + k;// waveY隨著x的值改變而改變,從而得到正弦曲線
? ? ? ? ? wave.lineTo(x, waveY); ? //從上一個繪制點畫一條線到(x,waveY);
? ? ?}
? ? ?wave.lineTo(width, height); //右下角,坐標(width, height),移動到右下角結束點,整體形成一個閉合路徑
? ? ?painter.setBrush(Qt::green); //填充綠色
? ? ?painter.drawPath(wave); ? ? ?//繪制出圖形
}
void Triangle::timerEvent(QTimerEvent *event)
{
? ? Q_UNUSED(event);
? ? this->update();
}
效果如圖四所示?

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖四:動態正弦曲線(水波效果)
?

總結

以上是生活随笔為你收集整理的QT-QPainter绘制曲线等基本图形的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。