先上效果圖
由於項目要涉及芯片檢測的功能,需要選擇特定區域,所以製作了個區域選擇框,
核心代碼1:DrawQWidget.h
#ifndef DRAWQWIDGET_H
#define DRAWQWIDGET_H
#include <QWidget>
#include <QKeyEvent>
#include <qpoint.h>
#include <qpen.h>
/*
*
*/
typedef enum draw_shap_e{
DRAW_RECT, //畫矩形
DRAW_ELLIPSE, //畫橢圓
DRAW_NO //不畫
}DRAW_SHAP_E;
/* 用來表示鼠標在矩形區域的位置信息
*
*/
typedef enum rect_mouse_position_e{
RECT_UPPER=0, //上邊緣
RECT_LOWER=1, //下邊緣
RECT_LEFT, //左邊緣
RECT_RIGHT, //右邊緣
RECT_LEFTUPPER, //左上角
RECT_LEFTLOWER, //左下角
RECT_RIGHTLOWER, //右下角
RECT_RIGHTUPPER, //右上角
RECT_INSIDE, //區域內部
RECT_OUTSIDE //區域外部
}RECT_MOUSE_POSITION_E;
/* 用來表示鼠標在橢圓區域的位置信息
*
*/
typedef enum ellipse_mouse_position_e{
ELLIPSE_UPPER=0, //上頂角
ELLIPSE_LOWER=1, //下頂角
ELLIPSE_LEFT, //左頂角
ELLIPSE_RIGHT, //右頂角
ELLIPSE_INSIDE, //區域內部
ELLIPSE_OUTSIDE //區域外部
}ELLIPSE_MOUSE_POSITION_E;
class DrawQWidget : public QWidget
{
Q_OBJECT
public:
explicit DrawQWidget(QWidget *parent = 0);
~DrawQWidget();
void set_draw_shap(DRAW_SHAP_E d);
void set_picture_image(QString file_name);
protected:
void timerEvent(QTimerEvent*);
void paintEvent(QPaintEvent*) override;
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private:
bool is_mouse_pressed;//是否按下鼠標
DRAW_SHAP_E draw_shap;
QPoint new_mouse_pos;
QPoint old_mouse_pos;
int m_difference_x;
int m_difference_y;
QPainter *painter; //用來繪製圖像
QPen frame_pen; //用來繪製區域邊框
QPen red_point_pen; //用來繪製紅色點
const int BoundaryRange = 6;//用來表示邊界的寬度範圍,用於拖拽
/* 矩形區域相關變量和函數
* 注意:QPoint的0點是左上角,橫向向右爲X的正方向,豎向向下爲Y的正方向
*/
int rect_left; //表示矩形右上角的X座標
int rect_top; //表示矩形右上角的Y座標
int rect_width; //表示矩形的寬(即水平長度)
int rect_height; //表示矩形的高(即垂直長度)
int rect_top_left_x, rect_top_left_y; //左上
int rect_top_right_x, rect_top_right_y; //右上
int rect_low_left_x, rect_low_left_y; //左下
int rect_low_right_x, rect_low_right_y; //右下
QPolygon rect_polygon; //裝載8個紅點的座標
RECT_MOUSE_POSITION_E rect_mouse_pos;
void rect_init_region();
void rect_update_region();
void rect_change_region();
RECT_MOUSE_POSITION_E rect_get_mouse_pos(int pos_x, int pos_y);
/* 橢圓區域相關變量和函數
* 注意:drawEllipse(20,20,210,160);
* 第1,2個參數表示圓/橢圓距屏幕左上角的像素數,第3,4個參數表示圓/橢圓的寬度和高度。
* 更加確切地表述,這個圓或橢圓是在矩形中,這個矩形的左上角的頂點在座標軸中的位置爲(20,20),
* 這個圓或橢圓的中心爲這個矩形的中心
*/
int ellipse_left; //表示橢圓右上角的X座標
int ellipse_top; //表示橢圓右上角的Y座標
int ellipse_width; //表示橢圓的寬(即水平長度)
int ellipse_height; //表示橢圓的高(即垂直長度)
int ellipse_middle_x;
int ellipse_middle_y;
QPolygon ellipse_polygon; //裝載4個紅點的座標
ELLIPSE_MOUSE_POSITION_E ellipse_mouse_pos;
void ellipse_init_region();
void ellipse_update_region();
void ellipse_change_region();
ELLIPSE_MOUSE_POSITION_E ellipse_get_mouse_pos(int pos_x, int pos_y);
/* other
*
*/
int timer_id;
QImage picture_image;
int picture_image_w;
int picture_image_h;
public slots:
};
#endif // DRAWQWIDGET_H
核心代碼2:DrawQWidget.cpp
#include "DrawQWidget.h"
#include <qdebug.h>
#include <qpainter.h>
DrawQWidget::DrawQWidget(QWidget *parent) : QWidget(parent)
{
setAttribute(Qt::WA_StyledBackground);
setStyleSheet("background-color: rgb(0, 0, 0);");
grabKeyboard();
setMouseTracking(true);
m_difference_x = 0;
m_difference_y = 0;
draw_shap = DRAW_NO;
painter = new QPainter(this);
frame_pen = QPen(QColor(0,174,255),2);
red_point_pen = QPen(QColor(255,0,0),4);
is_mouse_pressed = false;
timer_id = startTimer(20);
rect_init_region();
ellipse_init_region();
/// 開啓鼠標實時追蹤
setMouseTracking(true);
}
DrawQWidget::~DrawQWidget()
{
killTimer(timer_id);
}
/* Event function
*
*/
void DrawQWidget::timerEvent(QTimerEvent *)
{
this->update();
}
void DrawQWidget::paintEvent(QPaintEvent *)
{
painter->begin(this);
painter->drawImage(QRectF(0,0,width(),height()), picture_image);
switch (draw_shap) {
case (DRAW_RECT) :{
painter->setPen(frame_pen);//繪製邊框線
painter->drawRect(QRect(rect_left, rect_top, rect_width, rect_height));
painter->setPen(red_point_pen);//繪製八個點
painter->drawPoints(rect_polygon);
}break;
case (DRAW_ELLIPSE) :{
painter->setPen(frame_pen);//繪製邊框線
painter->drawEllipse(QRect(ellipse_left, ellipse_top, ellipse_width, ellipse_height));
painter->setPen(red_point_pen);//繪製四個點
painter->drawPoints(ellipse_polygon);
}break;
case (DRAW_NO) :break;
}
painter->end();
}
void DrawQWidget::mousePressEvent(QMouseEvent *event)
{
// if (!is_start_draw) return;
is_mouse_pressed = true;
}
void DrawQWidget::mouseMoveEvent(QMouseEvent *event)
{
// if (!is_start_draw) return;
new_mouse_pos = event->pos();
if (is_mouse_pressed) {
m_difference_x = new_mouse_pos.x() - old_mouse_pos.x();
m_difference_y = new_mouse_pos.y() - old_mouse_pos.y();
switch (draw_shap) {
case (DRAW_RECT) :rect_change_region();break;
case (DRAW_ELLIPSE) :ellipse_change_region();break;
case (DRAW_NO) :break;
}
}else{
switch (draw_shap) {
case (DRAW_RECT) :rect_mouse_pos = rect_get_mouse_pos(new_mouse_pos.x(), new_mouse_pos.y());break;
case (DRAW_ELLIPSE) :ellipse_mouse_pos = ellipse_get_mouse_pos(new_mouse_pos.x(), new_mouse_pos.y());break;
case (DRAW_NO) :break;
}
}
old_mouse_pos = new_mouse_pos;
}
void DrawQWidget::mouseReleaseEvent(QMouseEvent *event)
{
// if (!is_start_draw) return;
is_mouse_pressed = false;
}
/* Rect function
*
*/
void DrawQWidget::rect_init_region()
{
rect_left = 100;
rect_top = 200;
rect_width = 101;
rect_height = 101;
rect_mouse_pos = RECT_OUTSIDE;
rect_update_region();
}
void DrawQWidget::rect_update_region()
{
rect_top_left_x = rect_left; rect_top_left_y = rect_top;
rect_top_right_x = rect_left+rect_width; rect_top_right_y = rect_top;
rect_low_left_x = rect_left; rect_low_left_y = rect_top+rect_height;
rect_low_right_x = rect_left+rect_width; rect_low_right_y = rect_top+rect_height;
int Middle_X = rect_left + (rect_width>>1);
int Middle_Y = rect_top + (rect_height>>1);
rect_polygon.clear();
rect_polygon<<QPoint(Middle_X, rect_top) //上中
<<QPoint(rect_top_right_x, Middle_Y) //右中
<<QPoint(Middle_X, rect_low_left_y) //下中
<<QPoint(rect_left, Middle_Y) //左中
<<QPoint(rect_left, rect_top) //左上角
<<QPoint(rect_top_right_x, rect_top) //右上角
<<QPoint(rect_top_right_x, rect_low_left_y) //右下角
<<QPoint(rect_left, rect_low_left_y); //左下角
}
void DrawQWidget::rect_change_region()
{
switch (rect_mouse_pos) {
case (RECT_UPPER): rect_top += m_difference_y; rect_height -= m_difference_y;break;//上邊界
case (RECT_LOWER): rect_height += m_difference_y;break; //下邊界
case (RECT_LEFT) : rect_left += m_difference_x; rect_width -= m_difference_x;break;//左邊界
case (RECT_RIGHT): rect_width += m_difference_x;break; //右邊界
case (RECT_LEFTUPPER) : {//左上角
rect_top += m_difference_y; rect_height -= m_difference_y;
rect_left += m_difference_x; rect_width -= m_difference_x;
}break;
case (RECT_LEFTLOWER) : {//左下角
rect_height += m_difference_y;
rect_left += m_difference_x; rect_width -= m_difference_x;
}break;
case (RECT_RIGHTLOWER) : {//右下角
rect_height += m_difference_y;
rect_width += m_difference_x;
}break;
case (RECT_RIGHTUPPER) : {//右上角
rect_top += m_difference_y; rect_height -= m_difference_y;
rect_width += m_difference_x;
}break;
case (RECT_INSIDE) : {//內部
rect_top += m_difference_y;rect_left += m_difference_x;
}break;
case (RECT_OUTSIDE) : return;//外部
}
rect_update_region();
}
RECT_MOUSE_POSITION_E DrawQWidget::rect_get_mouse_pos(int pos_x, int pos_y)
{
if (pos_x < rect_top_left_x || pos_x > rect_top_right_x || pos_y < rect_top_left_y || pos_y > rect_low_left_y) {
this->setCursor(QCursor(Qt::ArrowCursor));
return RECT_OUTSIDE;
}else if (pos_y <= rect_top_left_y+BoundaryRange){ //1:左上角 2:右上角 3:上邊緣
if (pos_x <= rect_top_left_x+BoundaryRange) {this->setCursor(QCursor(Qt::SizeFDiagCursor));return RECT_LEFTUPPER;}
else if (pos_x >= rect_top_right_x-BoundaryRange){this->setCursor(QCursor(Qt::SizeBDiagCursor));return RECT_RIGHTUPPER;}
else {this->setCursor(QCursor(Qt::SizeVerCursor)); return RECT_UPPER;}
}else if (pos_y >= rect_low_left_y-BoundaryRange){ //1:左下角 2:右下角 3:下邊緣
if (pos_x <= rect_low_left_x+BoundaryRange) {this->setCursor(QCursor(Qt::SizeBDiagCursor));return RECT_LEFTLOWER;}
else if (pos_x >= rect_low_right_x-BoundaryRange){this->setCursor(QCursor(Qt::SizeFDiagCursor));return RECT_RIGHTLOWER;}
else {this->setCursor(QCursor(Qt::SizeVerCursor)); return RECT_LOWER;}
}else if (pos_x <= rect_top_left_x+BoundaryRange) { //左邊緣
this->setCursor(QCursor(Qt::SizeHorCursor)); return RECT_LEFT;
}else if (pos_x >= rect_top_right_x-BoundaryRange) { //右邊緣
this->setCursor(QCursor(Qt::SizeHorCursor)); return RECT_RIGHT;
}else {
this->setCursor(QCursor(Qt::SizeAllCursor));
return RECT_INSIDE;
}
}
/* Ellipse function
*
*/
void DrawQWidget::ellipse_init_region()
{
ellipse_left = 100;
ellipse_top = 200;
ellipse_width = 101;
ellipse_height = 101;
ellipse_mouse_pos = ELLIPSE_OUTSIDE;
ellipse_update_region();
}
void DrawQWidget::ellipse_update_region()
{
ellipse_middle_x = ellipse_left + (ellipse_width>>1);
ellipse_middle_y = ellipse_top + (ellipse_height>>1);
ellipse_polygon.clear();
ellipse_polygon<<QPoint(ellipse_middle_x, ellipse_top) //上頂角
<<QPoint(ellipse_left+ellipse_width, ellipse_middle_y) //右頂角
<<QPoint(ellipse_middle_x, ellipse_top+ellipse_height) //下頂角
<<QPoint(ellipse_left, ellipse_middle_y); //左頂角
}
void DrawQWidget::ellipse_change_region()
{
switch (ellipse_mouse_pos) {
case (ELLIPSE_UPPER) : ellipse_top += m_difference_y; ellipse_height -= m_difference_y;break;
case (ELLIPSE_LOWER) : ellipse_height += m_difference_y;break;
case (ELLIPSE_LEFT) : ellipse_left += m_difference_x; ellipse_width -= m_difference_x;break;
case (ELLIPSE_RIGHT) : ellipse_width += m_difference_x;break;
case (ELLIPSE_INSIDE) : ellipse_top += m_difference_y;ellipse_left += m_difference_x;break;
case (ELLIPSE_OUTSIDE): return;
}
ellipse_update_region();
}
ELLIPSE_MOUSE_POSITION_E DrawQWidget::ellipse_get_mouse_pos(int pos_x, int pos_y)
{
if (pos_x < ellipse_left || pos_x > (ellipse_left+ellipse_width) || pos_y < ellipse_top || pos_y > (ellipse_top+ellipse_height)) {
this->setCursor(QCursor(Qt::ArrowCursor));
return ELLIPSE_OUTSIDE;
}else if (pos_y <= ellipse_top+BoundaryRange){ //上頂角
if (pos_x >= (ellipse_middle_x-3) && pos_x <= (ellipse_middle_x+3)){
this->setCursor(QCursor(Qt::SizeVerCursor)); return ELLIPSE_UPPER;
}else{
this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;
}
}else if (pos_y >= ellipse_top+ellipse_height-BoundaryRange){ //下頂角
if (pos_x >= (ellipse_middle_x-3) && pos_x <= (ellipse_middle_x+3)) {
this->setCursor(QCursor(Qt::SizeVerCursor)); return ELLIPSE_LOWER;
}else{
this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;
}
}else if (pos_x <= ellipse_left+BoundaryRange) { //左頂角
if (pos_y >= (ellipse_middle_y-3) && pos_y <= (ellipse_middle_y+3)) {
this->setCursor(QCursor(Qt::SizeHorCursor)); return ELLIPSE_LEFT;
}else{
this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;
}
}else if (pos_x >= ellipse_left+ellipse_width-BoundaryRange) { //右頂角
if (pos_y >= (ellipse_middle_y-3) && pos_y <= (ellipse_middle_y+3)) {
this->setCursor(QCursor(Qt::SizeHorCursor)); return ELLIPSE_RIGHT;
}else{
this->setCursor(QCursor(Qt::SizeAllCursor)); return ELLIPSE_INSIDE;
}
}else {
this->setCursor(QCursor(Qt::SizeAllCursor));
return ELLIPSE_INSIDE;
}
}
/* other function
*
*/
void DrawQWidget::set_draw_shap(DRAW_SHAP_E d)
{
draw_shap = d;
}
void DrawQWidget::set_picture_image(QString file_name)
{
QImage image_tmp;
image_tmp.load(file_name);
if (!image_tmp.isNull()){
picture_image = image_tmp;
picture_image_w = image_tmp.width();
picture_image_h = image_tmp.height();
}
}
在QWidget上繪製區域框,可以放大縮小移動,可以是矩形,也可以是橢圓,註釋非常完整。
完整項目源碼:https://download.csdn.net/download/qq_40732350/12032761
沒有積分的朋友可以到淘寶代理下載,只要一塊錢(不限積分)