加入头文件 #include <graphics.h> 时遇到问题。
解决方法:
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类型的形参不兼容,这样设置。