C++实现鼠标手写+自绘按钮

学习视频链接: https://www.bilibili.com/video/BV12f4y1z776?spm_id_from=333.880.my_history.page.click&vd_source=b91967c499b23106586d7aa35af46413

加入头文件 #include <graphics.h> 时遇到问题。

解决方法:

链接: https://blog.csdn.net/suoyue_py/article/details/103799336?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2-103799336-blog-109754222.pc_relevant_aa&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2-103799336-blog-109754222.pc_relevant_aa&utm_relevant_index=5

在这里插入图片描述
EasyX软件的下载链接如下:https://easyx.cn/,打开后会自动根据电脑上的 VS 版本进行识别,默认点击安装即可。

代码功能

1、左键按下画圆,右键按下画方

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>

#include <conio.h> //使用该库中的 _getch() 函数,目的是为了防止闪屏

/*
	1. 创建图像化窗口
	2. 鼠标能反馈给计算机(窗口)的是什么?
	   鼠标移动、左键、右键 --》坐标值
	   重点:怎么去获取这个坐标值
	3. C语言是如何定义变量的呢?
	   类型 变量名(int a)
	   对于鼠标操作来说,变量类型为 MOUSEMSG
	   因此,要进行鼠标操作首先需要定义一个 MOUSEMSG 类型的变量
	4. 如何去获取鼠标反馈给计算机的值呢?
	   利用 Windows API :GetMouseMsg();
	5. 对获取到的值进行区分(哪些是左键、右键)
	   m.uMsg: 讨论鼠标操作类型
	   WM_LBUTTONDOWN: 鼠标左键按下
	   WM_MOUSEMOVE: 鼠标移动

	   (Windows Message)

    6. 画圆和画方函数
	   画圆:circle(int x, int y, int r) -- 圆心坐标加半径
	   画方:rectangle(int x, int y, int endx, int endy) -- 左上角坐标和右下角坐标
	7. 鼠标的坐标值: m.x、m.y
 
*/


int main()
{
	// 创建图形化窗口,窗口大小这里设置为 800 x 600
	initgraph(800, 600);

	MOUSEMSG m;  //存放鼠标的值

	while (1)
	{
		m = GetMouseMsg();
		//左键画圆,右键画方
		switch (m.uMsg)
		{
		case WM_MOUSEMOVE:
			break;
		case WM_LBUTTONDOWN:
			circle(m.x, m.y, 5);
			break;
		case WM_RBUTTONDOWN:
			rectangle(m.x-5, m.y-5, m.x + 5, m.y + 5);
			break;
		}
	}

	_getch();//等待用户按键(点击关闭窗口),让程序停在这
	closegraph();//关闭窗口

	return 0;
}

运行效果如下,

在这里插入图片描述
使用 pyqt 实现类似功能的代码:

import sys
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtGui import QPainter, QPixmap
from PyQt6.QtCore import Qt, QRect


class DrawWidget(QWidget):
    def __init__(self):
        super(DrawWidget, self).__init__()
        self._rects = [QRect()]
        self.setWindowTitle("绘图")
        self._begin = self.pos()
        self._lpress = False
        self._drag = False
        self.pix = QPixmap()
        self.initUi()

    def initUi(self):
        self.resize(512, 512)
        # 画布大小为 400 * 400 ,背景为白色
        self.pix = QPixmap(512, 512)
        self.pix.fill(Qt.GlobalColor.white)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.begin(self)
        painter.drawPixmap(0, 0, self.pix)
        try:
            for i in self._rects:
                painter.drawRect(i)
        except Exception as e:
            print(e)
        # 绘制多边形
        painter.end()

    def mousePressEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            self._lpress = True  # 左键按下的标志
            if not self._drag:
                self._rects.append(QRect())
                lastRect = self._rects[-1]  # 拿到新矩形
                lastRect.setTopLeft(event.pos())  # 记录鼠标的坐标(新矩形的左上角坐标)

    def mouseMoveEvent(self, event):

        if self._lpress:
            if not self._drag:
                lastRect = self._rects[-1]  # 拿到新矩形
                lastRect.setBottomRight(event.pos())  # 更新矩形的右下角坐标

            self.update()


# 别的程序调用当前文件是不会执行一下程序的
if __name__ == '__main__':
    # 创建 QApplication 类的实例
    # sys.argv 获取命令行参数
    # 本质上是执行命令行程序, 只不过在命令行界面中访问了与 GUI 相关的 API, 所以会产生窗口
    app = QApplication(sys.argv)

    widget = DrawWidget()  # 创建主窗口对象

    widget.show()

    # 进入程序的主循环、并通过exit函数确保主循环安全结束
    sys.exit(app.exec())

运行效果如下,
在这里插入图片描述

1、手写绘图板

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h> //使用该库中的 _getch() 函数,目的是为了防止闪屏

// 描述 点
struct Point
{
	int x;
	int y;

	Point()  //构造函数
	{
		x = -1;
		y = -1;
	}
	Point(int xx, int yy)  //构造函数
	{
		x = xx;
		y = yy;
	}
};

// 描述 线
struct LineTool
{
	int size;			// 粗细
	COLORREF color;		// 颜色
	Point begPos;       // 起始位置
	bool isLeftDown;        // 鼠标左键是否按下标志

	LineTool(int lineSize, COLORREF linecolor)
	{
		size   = lineSize;
		color  = linecolor;
		isLeftDown = false;  // 没有按下
	}
	// 鼠标处理
	void callMouse(MOUSEMSG m)
	{
		// 按下左键的处理
		if(m.uMsg == WM_LBUTTONDOWN)
		{ 
			isLeftDown = true;
			begPos = Point(m.x, m.y);
		}
		// 左键弹起的处理
		if (m.uMsg == WM_LBUTTONUP)
		{
			isLeftDown = false;
		}
		// 双键(鼠标左键按下且移动)动作的描述
		if (m.uMsg == WM_MOUSEMOVE && isLeftDown)
		{
			// 设置线的样式
			setlinestyle(PS_ENDCAP_ROUND, size);  // 圆头和线的粗细
			setlinecolor(color);  // 线的颜色
			line(begPos.x, begPos.y, m.x, m.y);
		}
		//每次画线结束后 — 改变起始画线的位置
		begPos = Point(m.x, m.y);

		// 清除效果 — 右键清除
		if (m.uMsg == WM_RBUTTONDOWN)
		{
			setbkcolor(WHITE); // 设置界面背景为白色
			cleardevice();	   // 刷新一下界面
		}
	}
};


int main()
{
	// 创建图形化窗口,窗口大小这里设置为 800 x 600
	initgraph(800, 600);
	setbkcolor(WHITE); // 设置界面背景为白色
	cleardevice();	   // 刷新一下界面
	
	LineTool* pLine = new LineTool(5, RED);

	while (1)
	{
		// 如果有鼠标操作
		while (MouseHit())  
		{
			MOUSEMSG m = GetMouseMsg();
			pLine->callMouse(m);
		}

		// 如果有按键操作
		if (_kbhit())
		{
			char userKey = _getch();  //获取按键
			//按键的值
			if (userKey == '+')
			{
				pLine->size++;
			}
			if (userKey == '-')
			{
				pLine->size--;
			}
			if (userKey == '\r')
			{
				saveimage("new.png");
				break;
			}
		}
	}
	delete pLine;
	pLine = NULL;

	_getch();//等待用户按键(点击关闭窗口),让程序停在这
	closegraph();//关闭窗口

	return 0;
}

运行效果如下,

在这里插入图片描述
按回车之后,

在这里插入图片描述
注意事项:

1、callMouse(MOUSEMSG m) 函数中的代码很重要。

//每次画线结束后 — 改变起始画线的位置
		begPos = Point(m.x, m.y);

2、注意中英文状态的切换,程序中的 ‘+’ 和 ‘-’ 都是在英文输入法状态下才起作用的。

3、关于 saveimage(“new.png”); 函数。

如果报错

const char 类型的实参与LPCWSTR类型的形参不兼容,这样设置。

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuechanba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值