海康工业相机驱动

1.新建基于对话框的MFC程序,界面布局如下

2.修改控件ID,为控件绑定变量

3.创建全局变量,构造函数中初始化变量,初始化对话框界面,补齐各控件按钮响应函数

全文程序如下:


// MFC_GrabimageDlg.h : 头文件
//#pragma once
#include"MvCameraControl.h"
#include "afxwin.h"// CMFC_GrabimageDlg 对话框
class CMFC_GrabimageDlg : public CDialogEx
{
// 构造
public:CMFC_GrabimageDlg(CWnd* pParent = NULL);	// 标准构造函数~CMFC_GrabimageDlg();	// 
// 对话框数据enum { IDD = IDD_MFC_GRABIMAGE_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()public:void* handle;//用于存放相机句柄MV_SAVE_IAMGE_TYPE m_enSaveImageType;//用于存储保存图片的类型MV_DISPLAY_FRAME_INFO stDisplayInfo;//原始数据转换int m_imagenum;//图像采集的帧号afx_msg void OnBnClickedButtonOpen();afx_msg void OnBnClickedButtonClose();afx_msg void OnBnClickedButtonGrabimage();CStatic m_picture;//PictureCtrl控件变量afx_msg void OnBnClickedButtonSave();afx_msg void OnBnClickedRadioBmp();afx_msg void OnBnClickedRadioIpg();afx_msg void OnBnClickedRadioPng();afx_msg void OnBnClickedRadioTif();
};
// MFC_GrabimageDlg.cpp : 实现文件
//#include "stdafx.h"
#include "MFC_Grabimage.h"
#include "MFC_GrabimageDlg.h"
#include "afxdialogex.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx
{
public:CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
protected:DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()// CMFC_GrabimageDlg 对话框CMFC_GrabimageDlg::CMFC_GrabimageDlg(CWnd* pParent /*=NULL*/): CDialogEx(CMFC_GrabimageDlg::IDD, pParent)
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);handle = NULL;m_enSaveImageType = MV_Image_Bmp;//先默认为bmp格式,后续添加单选按钮来获取,保存的图像类型格式
}void CMFC_GrabimageDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_PICTURE, m_picture);
}BEGIN_MESSAGE_MAP(CMFC_GrabimageDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON_OPEN, &CMFC_GrabimageDlg::OnBnClickedButtonOpen)ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CMFC_GrabimageDlg::OnBnClickedButtonClose)ON_BN_CLICKED(IDC_BUTTON_GRABIMAGE, &CMFC_GrabimageDlg::OnBnClickedButtonGrabimage)ON_BN_CLICKED(IDC_BUTTON_SAVE, &CMFC_GrabimageDlg::OnBnClickedButtonSave)ON_BN_CLICKED(IDC_RADIO_BMP, &CMFC_GrabimageDlg::OnBnClickedRadioBmp)ON_BN_CLICKED(IDC_RADIO_IPG, &CMFC_GrabimageDlg::OnBnClickedRadioIpg)ON_BN_CLICKED(IDC_RADIO_PNG, &CMFC_GrabimageDlg::OnBnClickedRadioPng)ON_BN_CLICKED(IDC_RADIO_TIF, &CMFC_GrabimageDlg::OnBnClickedRadioTif)
END_MESSAGE_MAP()// CMFC_GrabimageDlg 消息处理程序BOOL CMFC_GrabimageDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);			// 设置大图标SetIcon(m_hIcon, FALSE);		// 设置小图标// TODO:  在此添加额外的初始化代码// 默认选中IDC_RADIO_BMPCheckRadioButton(IDC_RADIO_BMP, IDC_RADIO_TIF, IDC_RADIO_BMP);//单选按钮设置return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}void CMFC_GrabimageDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}
}// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。void CMFC_GrabimageDlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFC_GrabimageDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}void CMFC_GrabimageDlg::OnBnClickedButtonOpen()
{// TODO:  在此添加控件通知处理程序代码//https://blog.csdn.net/weixin_44840658/article/details/89174782//枚举相机//先定义一个设备列表,用来存放枚举到的设备MV_CC_DEVICE_INFO_LIST cam_List;//列表 用于存放枚举到的相机列表//枚举int nRet = MV_OK;nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE, &cam_List);if (MV_OK != nRet){MessageBox(_T("枚举相机失败"));return ;}else//找到相机{//枚举到相机后,就可以获取到相机的一些设备信息//打印设备的SN码、设备名称、制造商//获取枚举到的相机数量int cam_num = cam_List.nDeviceNum;CString str;str.Format(_T("相机数量:%d"), cam_num);MessageBox(str);//留给后边研究,没有运行成功MV_CC_DEVICE_INFO* p_cam_Info = cam_List.pDeviceInfo[0];//相机相关参数输出//PrintDeviceInfo(p_cam_Info);//检查指定设备是否可访问int MV_A = MV_CC_IsDeviceAccessible(p_cam_Info, MV_ACCESS_Control);if (!MV_A){MessageBox(_T("设备不允许访问!"));return;}else{MessageBox(_T("设备允许访问!"));}}//创建相机句柄int nRet2 = MV_OK;nRet2 = MV_CC_CreateHandle(&handle, cam_List.pDeviceInfo[0]);//枚举相机列表中的第一个相机if (MV_OK != nRet2){MessageBox(_T("创建句柄失败!"));return;}//打开相机int nRet3 = MV_OK;nRet3 = MV_CC_OpenDevice(handle);if (MV_OK != nRet3){MessageBox(_T("相机打开失败!"));return;}
}void CMFC_GrabimageDlg::OnBnClickedButtonClose()
{// TODO:  在此添加控件通知处理程序代码//关闭相机int nRet4 = MV_OK;nRet4 = MV_CC_CloseDevice(handle);if (MV_OK != nRet4){MessageBox(_T("相机关闭失败!"));return;}else{MessageBox(_T("相机关闭成功!"));}//销毁句柄if (handle != NULL){MV_CC_DestroyHandle(handle);handle = NULL;}
}void CMFC_GrabimageDlg::OnBnClickedButtonGrabimage()
{// TODO:  在此添加控件通知处理程序代码int nRet = MV_OK;//开始取流// Start grab imagenRet = MV_CC_StartGrabbing(handle);if (MV_OK != nRet){MessageBox(_T("取流失败!!"));return ;}MV_FRAME_OUT stImageInfo = { 0 };//MV_DISPLAY_FRAME_INFO stDisplayInfo = { 0 };stDisplayInfo = { 0 };HWND p_hwnd = m_picture.m_hWnd;//获取控件的窗口句柄CRect rect;m_picture.GetClientRect(&rect);int width = rect.Width();   // 控件的宽度int height = rect.Height(); // 控件的高度nRet = MV_CC_GetImageBuffer(handle, &stImageInfo, 1000);if (nRet == MV_OK){CString str;str.Format(_T("相机采集图像的宽度:%d"), stImageInfo.stFrameInfo.nWidth);MessageBox(str);str.Format(_T("相机采集图像的高度:%d"), stImageInfo.stFrameInfo.nHeight);MessageBox(str);m_imagenum = stImageInfo.stFrameInfo.nFrameNum;str.Format(_T("相机采集图像的帧号:%d"), m_imagenum);MessageBox(str);//将图片显示在PictureCtrl控件窗口上if (p_hwnd){stDisplayInfo.hWnd = p_hwnd;stDisplayInfo.pData = stImageInfo.pBufAddr;// 指向图像数据的指针stDisplayInfo.nDataLen = stImageInfo.stFrameInfo.nFrameLen;//数据长度 stDisplayInfo.nWidth = stImageInfo.stFrameInfo.nWidth;   // 图像的宽度(像素)//stDisplayInfo.nWidth = width; // 图像的宽度(像素)用控件的宽度来代替stDisplayInfo.nHeight = stImageInfo.stFrameInfo.nHeight; // 图像的高度(像素//stDisplayInfo.nHeight = height;// 图像的高度(像素)用控件的高度来代替stDisplayInfo.enPixelType = stImageInfo.stFrameInfo.enPixelType;  // 像素类型,如黑白、RGB、Bayer等MV_CC_DisplayOneFrame(handle, &stDisplayInfo);//显示图像}MV_CC_FreeImageBuffer(handle, &stImageInfo);//需要用 MV_CC_FreeImageBuffer() 接口将pstFrame内的数据指针权限进行释放}else{MessageBox(_T("没有数据!"));}//停止采集// Stop grab imagenRet = MV_CC_StopGrabbing(handle);if (MV_OK != nRet){MessageBox(_T("停止采集失败!"));return ;}}CMFC_GrabimageDlg::~CMFC_GrabimageDlg()
{handle=NULL;
}void CMFC_GrabimageDlg::OnBnClickedButtonSave()
{// TODO:  在此添加控件通知处理程序代码MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam;memset(&stSaveFileParam, 0, sizeof(MV_SAVE_IMG_TO_FILE_PARAM));stSaveFileParam.enImageType = m_enSaveImageType; // ch:需要保存的图像类型 | en:Image format to savestSaveFileParam.enPixelType = stDisplayInfo.enPixelType;  // ch:相机对应的像素格式 | en:Camera pixel typestSaveFileParam.nWidth = stDisplayInfo.nWidth;         // ch:相机对应的宽 | en:WidthstSaveFileParam.nHeight = stDisplayInfo.nHeight;          // ch:相机对应的高 | en:HeightstSaveFileParam.nDataLen = stDisplayInfo.nDataLen;stSaveFileParam.pData = stDisplayInfo.pData;stSaveFileParam.iMethodValue = 0;// ch:jpg图像质量范围为(50-99], png图像质量范围为[0-9] | en:jpg image nQuality range is (50-99], png image nQuality range is [0-9]if (MV_Image_Bmp == stSaveFileParam.enImageType){sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.bmp", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);//这段代码使用了 `sprintf_s` 函数来格式化一个字符串,该字符串将用于存储图像文件的路径。`sprintf_s` 是一个安全版本的 `sprintf` 函数,用于格式化输出到一个字符数组中,它可以防止缓冲区溢出。//让我们详细分析一下这段代码://sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.bmp", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_stImageInfo.nFrameNum);// `stSaveFileParam.pImagePath`: 这是指向字符数组的指针,该数组将用来存储生成的文件路径字符串。这个数组应该足够大以容纳生成的字符串。//`256`: 这个数字是 `pImagePath` 指向的字符数组的大小,单位是字节。`sprintf_s` 需要知道目标缓冲区的大小,以避免写入超出边界。// `"Image_w%d_h%d_fn%03d.bmp"`: 这是格式化字符串,其中包含占位符 `%d` 和 `%03d`。`%d` 用于插入十进制整数,而 `%03d` 表示一个至少三位数的十进制数,不足部分用前导零填充。// `stSaveFileParam.nWidth`: 这是一个整数值,表示图像的宽度,它将被插入到第一个 `%d` 占位符的位置。// `stSaveFileParam.nHeight`: 这也是一个整数值,表示图像的高度,它将被插入到第二个 `%d` 占位符的位置。// `m_stImageInfo.nFrameNum`: 这是帧号,一个整数值,它将被插入到 `%03d` 占位符的位置,表示图像的序号,并确保至少有三位数字,不足则用零填充。//整个字符串 `"Image_w%d_h%d_fn%03d.bmp"` 将会被格式化成类似于 `"Image_w640_h480_fn001.bmp"` 的形式,其中 `w640`、`h480` 和 `fn001` 分别代表图像的宽度、高度和帧号。//这样做的目的是为了生成一个唯一的文件名,便于在保存图像时区分不同的图像文件,尤其是当有多张图像需要按顺序保存时。这种格式化字符串的方式在处理大量图像文件或需要动态生成文件名时非常常见。}else if (MV_Image_Jpeg == stSaveFileParam.enImageType){stSaveFileParam.nQuality = 80;sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.jpg", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);}else if (MV_Image_Tif == stSaveFileParam.enImageType){sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.tif", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);}else if (MV_Image_Png == stSaveFileParam.enImageType){stSaveFileParam.nQuality = 8;sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.png", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);}int nRet = MV_CC_SaveImageToFile(handle, &stSaveFileParam);if (MV_OK != nRet){MessageBox(_T("图像保存失败!"));return;}
}void CMFC_GrabimageDlg::OnBnClickedRadioBmp()
{// TODO:  在此添加控件通知处理程序代码m_enSaveImageType = MV_Image_Bmp;//设置图片为bmp格式
}void CMFC_GrabimageDlg::OnBnClickedRadioIpg()
{// TODO:  在此添加控件通知处理程序代码m_enSaveImageType = MV_Image_Jpeg;//设置图片为jpg格式
}void CMFC_GrabimageDlg::OnBnClickedRadioPng()
{// TODO:  在此添加控件通知处理程序代码m_enSaveImageType = MV_Image_Png;//设置图片为png格式
}void CMFC_GrabimageDlg::OnBnClickedRadioTif()
{// TODO:  在此添加控件通知处理程序代码m_enSaveImageType = MV_Image_Tif;//设置图片为tif格式
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45081.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【动态规划Ⅰ】斐波那契、爬楼梯、杨辉三角

动态规划—斐波那契系列 什么是动态规划斐波那契数组相关题目509. 斐波那契数 Easy1137. 第 N 个泰波那契数 Easy 杨辉三角118. 杨辉三角 Easy 爬楼梯相关题目70. 爬楼梯 Easy746. 使用最小花费爬楼梯 Easy 什么是动态规划 动态规划是一种通过将原问题分解为相对简单的子问题来…

近期几首小诗汇总-生活~卷

生活 为生活飘零&#xff0c;风雨都不阻 路见盲人艰&#xff0c;为她心点灯 贺中科大家长论坛成立十五周年 科学家园有喜贺 园外丑汉翘望中 曾一学子入我科 正育科二盼长大 憧憬也能入此家 与科学家论短长 园外翘首听高论 发现有隙入此坛 竟然也能注册成 入园浏览惶然立 此贴…

JAVA中的回溯算法解空间树,八皇后问题以及骑士游历问题超详解

1.回溯算法的概念 回溯算法顾名思义就是有回溯的算法 回溯算法实际上一个类似枚举的搜索尝试过程&#xff0c;主要是在搜索尝试过程中寻找问题的解&#xff0c;当发现已不满足求解条件时&#xff0c;就“回溯”返回&#xff0c;尝试别的路径。回溯法是一种选优搜索法&#xff…

[线性RNN系列] Mamba: S4史诗级升级

前言 iclr24终于可以在openreview上看预印本了 这篇&#xff08;可能是颠覆之作&#xff09;文风一眼c re组出品&#xff1b;效果实在太惊艳了&#xff0c;实验相当完善&#xff0c;忍不住写一篇解读分享分享。 TL;DR &#xff08;overview&#xff09; Structured State-Sp…

xshell公钥免密登录

设备&#xff1a;一台linux系统机器&#xff0c;一台windows系统机器 软件&#xff1a;xshell 要求&#xff1a;公钥免密登录 一、生成公钥、私钥 1、打开shell &#xff1b; 点击工具 &#xff1b; 新建用户生成密钥向导 2、生成密钥参数 密钥类型&#xff1a;RS…

element ui ts table重置排序

#日常# 今天带的实习生&#xff0c;在遇到开发过程中&#xff0c;遇到了element ui table 每次查询的时候都需要重置排序方式&#xff0c;而且多个排序是由前端排序。 <el-table :data"tableData" ref"restTable"> </<el-table> <script…

bi项目笔记

1.bi是什么 bi项目就是商业智能系统&#xff0c;也就是数据可视画、报表可视化系统&#xff0c;如下图的就是bi项目了 2.技术栈

Linux rsync文件同步工具

scp的不足 1. 性能问题 单线程传输 SCP只使用单线程进行传输&#xff0c;这意味着在传输大文件或大量小文件时&#xff0c;其传输速度和效率可能不如其他多线程工具。 无法压缩数据传输 SCP不支持内置的压缩机制&#xff0c;这在传输大文件时会导致带宽使用效率较低。 2.…

我花了5年时间训练自己这种能力,希望你也能成功

人生最重要的能力是日拱一卒&#xff0c;即每天做一点点对自己有利的事并持续足够长的时间。作者之前急于求成&#xff0c;减肥失败。同事通过每月改进一件小事成功减肥且知识储备丰富。作者受启发后&#xff0c;通过走楼梯、换代糖等小改变&#xff0c;用 4 年减了 40 斤&…

从头开始搭建一套Elasticsearch集群

前言 刚开始使用ES接触的就是rpm或者是云上提供的ES服务&#xff0c;基本上开箱即用。特别是云上的ES服务&#xff0c;开局就是集群版本&#xff0c;提供的是优化后的参数配置、开箱即匹配访问鉴权及常用插件&#xff0c;如无特殊需要基本上屏蔽了所有细节&#xff0c;直接可投…

深入了解 MySQL 的 EXPLAIN 命令

一、什么是 EXPLAIN 命令&#xff1f; EXPLAIN 命令用于显示 MySQL 如何执行某个 SQL 语句&#xff0c;尤其是 SELECT 语句。通过 EXPLAIN 命令&#xff0c;可以看到查询在实际执行前的执行计划&#xff0c;这对于优化查询性能至关重要。 二、EXPLAIN 的基本用法 要使用 EXP…

如何禁用键盘上的特定键或快捷方式?这里有详细步骤

要禁用特定的键盘键或快捷键吗&#xff1f;微软官方应用程序Microsoft PowerToys使这项任务变得非常简单。以下是使用Microsoft PowerToys中的键盘管理器禁用特定键或快捷方式的快速指南。 如果你还没有安装Microsoft PowerToys 如果你的设备上没有安装Microsoft PowerToys&a…

springboot上传图片

前端的name的值必须要和后端的MultipartFile 形参名一致 存储本地

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【匿名密钥证明(C/C++)】

匿名密钥证明(C/C) 在使用本功能时&#xff0c;需确保网络通畅。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 确定密钥别名keyAlias&#xff0c;密钥别名最大长度为64字节&#xff1b;初始化参数集&#xff1a;通过[OH_Huk…

css3 transform的旋转和位移制作太阳花

css3 transform 实例展示知识点rotate 旋转translate 位移transform: translate(300px,200px) rotate(90deg) 实例代码 实例展示 知识点 transform的两个属性 rotate 旋转 translate 位移 transform: translate(300px,200px) rotate(90deg) 实例代码 <!DOCTYPE html&g…

flask 定时任务(APScheduler)使用current_app app_context()上下文

前言: 描述&#xff1a;flask定时任务调用的方法中使用了current_app.logger.info()记录日志报错 报错代码 raise RuntimeError(unbound_message) from None RuntimeError: Working outside of application context.This typically means that you attempted to use functiona…

IDEA中Git常用操作及Git存储原理

Git简介与使用 Intro Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git是一款分布式版本控制系统&#xff08;VSC&#xff09;&#xff0c;是团队合作开发…

算法学习笔记(8.3)-(0-1背包问题)

目录 最常见的0-1背包问题&#xff1a; 第一步&#xff1a;思考每轮的决策&#xff0c;定义状态&#xff0c;从而得到dp表 第二步&#xff1a;找出最优子结构&#xff0c;进而推导出状态转移方程 第三步&#xff1a;确定边界条件和状态转移顺序 方法一&#xff1a;暴力搜素…

MFC之对话框--线宽/线型/颜色

文章目录 线宽输入实现优化无法记录上一次线粗问题 线宽滑动实现实现选择线类型实现颜色选择总结 线宽输入实现 优化无法记录上一次线粗问题 线宽滑动实现 实现选择线类型 实现颜色选择 总结 1。创建新窗口&#xff08;dialog)会创建一个新的类&#xff0c;在类中实现窗口中的…

vue中父子传递属性值

1、父传子属性值 自定义图库组件 在add.vue中应用tuku组件并给默认值 效果 2、 子传父&#xff0c;逆向赋值 add.vue和第一问中一样 修改tuku组件&#xff0c;传值给add.vue 3、多个传递 效果&#xff1a; 点击两个修改按钮后 4、使用defineModel简化父子传值 其他代码跟…