HALCONVS .net混合编程案例【02】:检测芯片的管脚间距

news2024/10/2 16:22:36

前言:

本章给出的HALCON和Visual Studio的WPF项目中联合编程的案例。

VS中WPF的编程,UI的设计非常方便,如果结合HALCON的算法,可以很快实施机器视觉相关的应用。本例的应用,实现了自动检测的一个三洋的芯片的管脚的间距。
 


一、项目结果展示:

步骤一:读取图片

拍摄一张芯片PCB的图:

步骤二:构建模式

 对拍摄的图片,进行模式识别,这里构建了两个模式,模式1,OCR的文字识别,识别芯片上的文字。模式2,蓝色部分,实现对管脚的检测。

步骤三:检测时间匹配

对算法处理的节奏,进行处理

步骤四:管脚数量和间距检测


二、原理和设计说明:

2.1 设计说明: 

        HALCON和 VS WPF应用结合,在Visual Studio的WPF项目中,可以通过拖动工具箱中的控件到设计视图来自动生成XAML代码。这些代码定义了用户界面的布局和控件。熟悉,XML语言的同学,应该知道,XML的标记语言,掌握了基本语法后,理解起来是很容易的。

        拖动控件设计UI后,对于每个控件,你可以在其关联的code-behind文件中添加事件处理程序。就可以要编写或修改这些事件处理程序的代码,以实现你想要的功能。例如,某个按键控件的事件处理,Create_Click就是一个事件处理程序,它会在用户点击相关的按钮时被触发。

当然,为了实现具体的功能,你仍然需要编写和修改事件处理程序的代码。

2.1.1 XML的VS设计

XML显然可以作为一种方式,这里笔者给出了链接和案例参考:

微软 XML语言说明

在VS中编写XML实例程序

但是,XML的 方法不是,本例采用的语言,本例,采用AXML的方法。见下节:

2.1.2 AXML的设计

总的来说,虽然WPF的用户界面可以通过拖放控件来自动生成,但是HALCON的兼容界面设计,结合WPF似乎,采用AXML更方便。

【Franklin案】注意,这里提到的AXML和Android的AXML应该不是一个东西,别搞混了。

下面这个链接对AXML做了说明:

支付宝小程序 AXML 语法

上文,针对AXML语法大致做了如上说明:

AXML有五种语法,包括:数据绑定、条件渲染、列表渲染、模版、渲染。

具体,参考链接:

至于 Android的AXML是什么,参考如下:

安卓AXML图解

【Franklin案】所以,本项目中的AXML显然只是一句了AXML的对XML的一种裁剪的语言。


三、设计实例:

3.1 项目运行环境和配置:

本例,博主在WIN10+VS 2019上成功运行,需要如下.net的框架支持:

当然,作为HALCON混合编程,HALCONNET是必须的:

3.2 项目构建:

【Franklin案】我们大致了解一下,项目各个文件构建:

3.2.1 项目文件组成和各个文件的主要作用:

  1. Properties 文件夹:包含四个文件,用于管理应用程序资源和用户设置。

    • Resources.resx 和 Resources.Designer.cs:用于管理应用程序资源。这些文件包含一个名为 resourceMan 的 ResourceManager 类型的字段和一个名为 resourceCulture 的 CultureInfo 类型的字段,这些字段用于处理资源的本地化。
    • Settings.settings 和 Settings.Designer.cs:用于存储用户设置。这些文件包含一个名为 defaultInstance 的 Settings 类型的字段和一个名为 Default 的 Settings 类型的属性,这些字段和属性用于处理应用程序的设置。
  2. XAML 文件:在这个项目中,AXML文件实际上是XAML文件,主要用于定义用户界面,包括布局、样式和控件等。它们不是自动生成的,需要你设计和编码。

    • App.xaml:用于应用程序级别的资源和启动代码。
    • MatchingWindow.xaml:用于主窗口的用户界面定义。
  3. Code-behind 文件:每个XAML文件都有一个关联的code-behind文件,包含逻辑。

    • App.xaml.cs
    • MatchingWindow.xaml.cs:这个文件包含一个名为 MatchingWindow 的类,该类从 Window 类继承,并包含多个字段和方法。这些字段(如 FramegrabberImgImgWidthImgHeight 等)表明它与图像处理有关。这些方法(如 CreateBtn_Click 和 StopBtn_Click)表明它处理用户界面交互。
  4. 引用:项目还包含了多个库的引用,如 halcondotnetPresentationCorePresentationFrameworkSystemSystem.CoreSystem.Data.DataSetExtensionsSystem.DrawingSystem.XmlSystem.Xml.Linq 和 WindowsBase

3.2.2 UI的设计

UI的设计相对简单,就是拖动相关的控件到界面。

 3.2.3 对象浏览:

3.2.3.1 HalconDoNet (这是直接引用的)

混合编程,这个dll是最重要的,主要来自于你安装的HALCON的位置,博主的位置如下,作参考:


四,设计源码:

 4.1 UI界面源码:

<Window x:Class="MatchingWPF.MatchingWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MatchingWindow" Height="951.068" Width="1202.765" Background="#FFD4D0C8">
    <Grid Margin="10, 10, 10, 10">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition MaxHeight="100"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Grid Grid.Row="0" Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*">
                </ColumnDefinition>
                <ColumnDefinition MaxWidth="150"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
                <Button Name="CreateBtn" Click="CreateBtn_Click" Grid.Row="0" Grid.Column="1" MinHeight="40" Margin="10">Create Model</Button>
                <Button Name="StartBtn" Click="StartBtn_Click" Grid.Row="0" Grid.Column="1"  MinHeight="40" Margin="10">Start</Button>
                <Button Name="StopBtn" Click="StopBtn_Click" Grid.Row="0" Grid.Column="1"  MinHeight="40" Margin="10">Stop</Button>
            </StackPanel>
            <my:HSmartWindowControlWPF Loaded="hWindowControlWPF1_HInitWindow" Name="hWindowControlWPF1"
                                   xmlns:my="clr-namespace:HalconDotNet;assembly=halcondotnet" Grid.Column="0" Grid.Row="0" />
        </Grid>

        <Grid Grid.Row="1" Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <Label Name="MatchingLabel"      FontSize="12" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left">Matching:</Label>
            <Label Name="MatchingTimeLabel"  FontSize="12" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left">Time:</Label>
            <Label Name="MatchingScoreLabel" FontSize="12" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Left">Score:</Label>

            <Label Name="MeasureLabel"     FontSize="12" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left">Measure:</Label>
            <Label Name="MeasureTimeLabel" FontSize="12" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left">Time:</Label>
            <Label Name="MeasureNumLabel"  FontSize="12" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left">Number of leads:</Label>
            <Label Name="MeasureDistLabel" FontSize="12" Grid.Row="1" Grid.Column="3">Minimum lead distance:</Label>
        </Grid>
    </Grid>
</Window>

 4.2 界面控件的事件操作:

    private void CreateBtn_Click(object sender, RoutedEventArgs e)
    {
      HImage ImgReduced;
      HRegion Rectangle1 = new HRegion();
      HRegion Rectangle2 = new HRegion();

      CreateBtn.IsEnabled = false;
      Window.SetColor("red");
      Window.SetDraw("margin");
      Window.SetLineWidth(3);

      ImgReduced = Img.ReduceDomain(Rectangle);
      ImgReduced.InspectShapeModel(out ModelRegion, 1, 30);
      Rectangle1.GenRectangle2(Rect1Row, Rect1Col, RectPhi, RectLength1, RectLength2);
      Rectangle2.GenRectangle2(Rect2Row, Rect2Col, RectPhi, RectLength1, RectLength2);
      ShapeModel = new HShapeModel(ImgReduced, 4, 0, new HTuple(360.0).TupleRad().D,
                new HTuple(1.0).TupleRad().D, "none", "use_polarity", 30, 10);

      Window.SetColor("green");
      Window.SetDraw("fill");
      ModelRegion.DispObj(Window);
      Window.SetColor("blue");
      Window.SetDraw("margin");
      Rectangle1.DispObj(Window);
      Rectangle2.DispObj(Window);

      StopBtn.IsEnabled = false;
      StartBtn.IsEnabled = true;
    }

    private void StartBtn_Click(object sender, RoutedEventArgs e)
    {
      Timer.Start();
      CreateBtn.IsEnabled = false;
      StopBtn.IsEnabled = true;
      StartBtn.IsEnabled = false;
    }


    private void StopBtn_Click(object sender, RoutedEventArgs e)
    {
      Timer.Stop();
      CreateBtn.IsEnabled = false;
      StopBtn.IsEnabled = false;
      StartBtn.IsEnabled = true;
    }

    private void Timer_Tick(object sender, System.EventArgs e)
    {
      Action();
    }

4.3 HALCON的核心算法部分:

  private void Action()
    {
      double        S1, S2;
      HTuple        RowCheck, ColumnCheck, AngleCheck, Score;
      HHomMat2D     Matrix = new HHomMat2D();
      HRegion       ModelRegionTrans;
      HTuple        Rect1RowCheck, Rect1ColCheck;
      HTuple        Rect2RowCheck, Rect2ColCheck;
      HRegion       Rectangle1 = new HRegion();
      HRegion       Rectangle2 = new HRegion();
      HMeasure      Measure1, Measure2;
      HTuple        RowEdgeFirst1, ColumnEdgeFirst1;
      HTuple        AmplitudeFirst1, RowEdgeSecond1;
      HTuple        ColumnEdgeSecond1, AmplitudeSecond1;
      HTuple        IntraDistance1, InterDistance1;
      HTuple        RowEdgeFirst2, ColumnEdgeFirst2;
      HTuple        AmplitudeFirst2, RowEdgeSecond2;
      HTuple        ColumnEdgeSecond2, AmplitudeSecond2;
      HTuple        IntraDistance2, InterDistance2;
      HTuple        MinDistance;
      int         NumLeads;

      Img.Dispose();
      Img.GrabImage(Framegrabber);
      Img.DispObj(Window);

      // Find the IC in the current image.
      S1 = HSystem.CountSeconds();
      ShapeModel.FindShapeModel(Img, 0,
                  new HTuple(360).TupleRad().D,
                  0.7, 1, 0.5, "least_squares",
                  4, 0.9, out RowCheck, out ColumnCheck,
                  out AngleCheck, out Score);
      S2 = HSystem.CountSeconds();
      MatchingTimeLabel.Content = "Time: " +
        String.Format("{0,4:F1}", (S2 - S1)*1000) + "ms";
      MatchingScoreLabel.Content = "Score: ";

      if (RowCheck.Length == 1)
      {
        MatchingScoreLabel.Content = "Score: " +
                      String.Format("{0:F5}", Score.D);
        // Rotate the model for visualization purposes.
        Matrix.VectorAngleToRigid(new HTuple(Row), new HTuple(Column), new HTuple(0.0),
                      RowCheck, ColumnCheck, AngleCheck);

        ModelRegionTrans = ModelRegion.AffineTransRegion(Matrix, "false");
        Window.SetColor("green");
        Window.SetDraw("fill");
        ModelRegionTrans.DispObj(Window);
        // Compute the parameters of the measurement rectangles.
        Matrix.AffineTransPixel(Rect1Row, Rect1Col,
                    out Rect1RowCheck, out Rect1ColCheck);
        Matrix.AffineTransPixel(Rect2Row, Rect2Col, out Rect2RowCheck,
                    out Rect2ColCheck);

        // For visualization purposes, generate the two rectangles as
        // regions and display them.
        Rectangle1.GenRectangle2(Rect1RowCheck.D, Rect1ColCheck.D,
                    RectPhi + AngleCheck.D,
                    RectLength1, RectLength2);
        Rectangle2.GenRectangle2(Rect2RowCheck.D, Rect2ColCheck.D,
                    RectPhi + AngleCheck.D,
                    RectLength1, RectLength2);
        Window.SetColor("blue");
        Window.SetDraw("margin");
        Rectangle1.DispObj(Window);
        Rectangle2.DispObj(Window);
        // Do the actual measurements.
        S1 = HSystem.CountSeconds();
        Measure1 = new HMeasure(Rect1RowCheck.D, Rect1ColCheck.D,
                    RectPhi + AngleCheck.D,
                    RectLength1, RectLength2,
                    ImgWidth, ImgHeight, "bilinear");
        Measure2 = new HMeasure(Rect2RowCheck.D, Rect2ColCheck.D,
                    RectPhi + AngleCheck.D,
                    RectLength1, RectLength2,
                    ImgWidth, ImgHeight, "bilinear");
        Measure1.MeasurePairs(Img, 2, 90,
                  "positive", "all",
                  out RowEdgeFirst1,
                  out ColumnEdgeFirst1,
                  out AmplitudeFirst1,
                  out RowEdgeSecond1,
                  out ColumnEdgeSecond1,
                  out AmplitudeSecond1,
                  out IntraDistance1,
                  out InterDistance1);
        Measure2.MeasurePairs(Img, 2, 90,
                  "positive", "all",
                  out RowEdgeFirst2,
                  out ColumnEdgeFirst2,
                  out AmplitudeFirst2,
                  out RowEdgeSecond2,
                  out ColumnEdgeSecond2,
                  out AmplitudeSecond2,
                  out IntraDistance2,
                  out InterDistance2);
        S2 = HSystem.CountSeconds();
        MeasureTimeLabel.Content = "Time: " +
          String.Format("{0,5:F1}", (S2 - S1)*1000) + "ms";
        Window.SetColor("red");
        Window.DispLine(RowEdgeFirst1 - RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeFirst1 - RectLength2*Math.Sin(AngleCheck),
                RowEdgeFirst1 + RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeFirst1 + RectLength2*Math.Sin(AngleCheck));
        Window.DispLine(RowEdgeSecond1 - RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeSecond1 - RectLength2*Math.Sin(AngleCheck),
                RowEdgeSecond1 + RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeSecond1 + RectLength2*Math.Sin(AngleCheck));
        Window.DispLine(RowEdgeFirst2 - RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeFirst2 - RectLength2*Math.Sin(AngleCheck),
                RowEdgeFirst2 + RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeFirst2 + RectLength2*Math.Sin(AngleCheck));
        Window.DispLine(RowEdgeSecond2 - RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeSecond2 - RectLength2*Math.Sin(AngleCheck),
                RowEdgeSecond2 + RectLength2*Math.Cos(AngleCheck),
                ColumnEdgeSecond2 + RectLength2*Math.Sin(AngleCheck));
        NumLeads = IntraDistance1.Length + IntraDistance2.Length;
        MeasureNumLabel.Content = "Number of leads: " +
                      String.Format("{0:D2}", NumLeads);
        MinDistance = InterDistance1.TupleConcat(InterDistance2).TupleMin();
        MeasureDistLabel.Content = "Minimum lead distance: " +
          String.Format("{0:F3}", MinDistance.D);
        Window.FlushBuffer();
        Measure1.Dispose();
        Measure2.Dispose();
      }
    }

  }

小结:

本例的应用,实现了自动检测的一个三洋的芯片的管脚的间距。

项目的完全源码,需要的读者朋友通过扫我博客微信图片,加我好友询问获取。

文章主要是实践HALCON的混合编程案例,如有错误,还望原谅,指出,谢谢大家!

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

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

相关文章

实验五 用户进程管理-实验部分

目录 一、知识点 1.Unix进程创建API 1.1.创建新进程API 1.2.fork()地址空间的复制 1.4.shell中调用fork()图示 1.5.fork()创建进程个数示例 1.6.fork()与exec()的比较 2.实验执行流程概述 3.创建用户进程 3.1.应用程序的组成和编译 3.2.用户进程的虚拟地址空间 3.3…

初识QT(上篇):What Qt

初识QT&#xff08;上篇&#xff09;&#xff1a;What Qt 前言 & 说明前言说明 初识QT1.1 QT的what1. 介绍2. 发展历程3. QT架构的主要内容4.QT的常用模块 1.2 QT的 why1. QT的核心机制 下篇笔记链接 前言 & 说明 前言 前言&#xff1a; 之前说要share的qt相关知识&am…

Hadoop入门学习笔记——五、在虚拟机中部署Hive

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 五、在虚拟机中部署Hive5.1. 在node1虚拟机安装MySQL5.2.…

正餐---二叉树的OJ题

目录​​​​​​​ 前言&#x1f36f; 1. 检查两颗树是否相同&#x1f947; 1.1 思路分析&#x1fa99; 1.2 代码实现&#x1f9f0; 2. 单值二叉树&#x1f332; 2.1 思路分析&#x1f52e; 2.2 代码实现&#x1f488; 3. 二叉树的前序遍历&#x1f39f;️ 3.1 思路分…

鲜花植物企业网站建设的效果如何

从整体来看&#xff0c;似乎鲜花植物只会在线下花市或花店里购买或见到&#xff0c;但其实对鲜花植物批发商或品牌商来说&#xff0c;线上渠道同样重要&#xff0c;从本地来说&#xff0c;流量少且获取难&#xff0c;各家品牌/门店竞争激烈&#xff0c;并且无法全面展示自己的品…

基于模型驱动的可解释性全色、多光谱、高光谱融合网络

摘要 摘要:同时融合高光谱(HS)、多光谱(MS)和全色(PAN)图像为生成高分辨率HS (HRHS)图像提供了一种新的范式。在这项研究中&#xff0c;我们提出了一个可解释的模型驱动的深度网络&#xff0c;用于HS, MS和PAN图像融合&#xff0c;称为HMPNet。我们首先提出了一种新的融合模型…

计算机组成原理第6章-(计算机的运算方法)【上】

机器数与真值 把符号“数字化”的数称为机器数,而把带“+”、“-”符号的数称为真值。 原码表示法 原码是机器数中最简单的一种表示形式,0表示整数,1表示负数。 约定整数的符号位和数值位之间用“逗号”隔开。 在原码中,0有两种表示形式:“+0”和“-0”是不一样的。 反…

毅速:3D打印随形水路已经逐步向压铸模具普及

随着科技的不断发展&#xff0c;3D打印技术已经逐渐渗透到各个领域。其中&#xff0c;3D打印随形水路在注塑模具中已经广泛应用&#xff0c;目前正逐渐向压铸模具普及。 传统CNC等减材工艺的水路制造&#xff0c;可以在模具中生产出平直的冷却水路&#xff0c;但这种工艺难以加…

Qt/C++视频监控Onvif工具/组播搜索/显示监控画面/图片参数调节/OSD管理/祖传原创

一、前言 能够写出简单易用而又不失功能强大的组件&#xff0c;一直是我的追求&#xff0c;简单主要体现在易用性&#xff0c;不能搞一些繁琐的流程和一些极难使用的API接口&#xff0c;或者一些看不懂的很难以理解的函数名称&#xff0c;一定是要越简单越好。功能强大主要体现…

百度网盘win11端扫一扫登录二维码无法显示问题的解决方法

百度网盘win11端扫一扫登录二维码无法显示问题的解决方法 文章目录 问题描述解决方法1、打开Edge 设置2、进入Reset settings页面3、单击重置按钮&#xff1a;4、重新打开百度网盘APP 问题描述 今天在win11端扫描登录百度云网盘时&#xff0c;二维码无法加载出来&#xff0c;具…

PCIe surprise down异常与DPC功能分析-part2

DPC是PCIe协议中的一项功能&#xff0c;旨在防止由于一个设备的错误而影响到整个系统。当一个PCIe设备检测到严重的、不可恢复的错误时&#xff0c;它可能会触发DPC过程。在这个过程中&#xff0c;PCIe开关会隔离受影响的下游端口&#xff0c;阻止任何进一步的数据传输和请求通…

中北大学 软件构造 U+及上课代码详解

作业1 1.数据类型可分为两类:(原子类型) 、结构类型。 2.(数据结构)是计算机存储、组织数据的方式&#xff0c;是指相互之间存在一种或多种特定关系的数据元素的集合 3.代码重构指的是改变程序的(结构)而不改变其行为&#xff0c;以便提高代码的可读性、易修改性等。 4.软件实…

语法分析树(先看例子再看定义)

语法分析树&#xff08;先看例子再看定义&#xff09; 先讲例子 书上讲问题&#xff0c;先讲定义&#xff0c;一顿学术操作&#xff0c;让人云里雾里&#xff0c;然后出例子。其实这样往往让人觉得看书的过程就是放弃的过程。 关于语法分析树&#xff0c;我先从上篇文章的例…

二叉树进阶题目(超详解)

文章目录 前言根据二叉树创建字符串题目分析写代码 二叉树的层序遍历题目分析 写代码二叉树的层序遍历II题目分析写代码 二叉树的最近公共祖先题目分析写代码时间复杂度 优化思路优化的代码 二叉搜索树与双向链表题目分析写代码 从前序与中序遍历序列构造二叉树题目分析写代码从…

线性回归简介

线性回归简介 1、情景描述2、线性回归 1、情景描述 假设&#xff0c;我们现在有这么一张图&#xff1a; 其中&#xff0c;横坐标x表示房子的面积&#xff0c;纵坐标y表示房价。我们猜想x与y之间存在线性关系&#xff1a; y k x b ykxb ykxb 现在&#xff0c;思考一个问题&…

PHP HTTPoxy CGI 应用程序漏洞 CVE-2016-5385

HTTPoxy CGI 应用程序漏洞 CVE-2016-5385 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议 漏洞名称 漏洞描述 在Oracle Communications BRM 10.x/12.x&#xff08;云软件&#xff09;中发现漏洞。它已经被宣布为关键。此漏洞影响组件用户数据库的未…

RabbitMQ如何做到不丢不重

目录 MQTT协议 如何保证消息100%不丢失 生产端可靠性投递 ​编辑 RabbitMQ的Broker端投 &#xff08;1&#xff09;消息持久化 &#xff08;2&#xff09;设置集群镜像模式 &#xff08;3&#xff09;消息补偿机制 消费端 ACK机制改为手动 总结 MQTT协议 先来说下MQTT…

springCould中的consul-从小白开始【4】

目录 1.consul介绍 ❤️❤️❤️ 2.安装 ❤️❤️❤️ 3.创建8006模块 ❤️❤️❤️ 4.创建80模块❤️❤️❤️ 1.consul介绍 ❤️❤️❤️ Consul 是一种用于服务发现、配置和分布式一致性的开源软件。它由HashiCorp开发和维护&#xff0c;可用于帮助构建和管理现代化的分布…

新建项目EasyUiAutotest,安装Appium-Python-Client

一、前置说明 Appium-Python-Client 是 Appium 的 Python 客户端库&#xff0c;它提供了一系列的类和方法&#xff0c;用于与 Appium 服务器进行通信&#xff0c;并执行各种移动应用测试操作&#xff0c;包括启动应用、模拟用户输入、点击等操作。 二、操作步骤 1. 启动Pych…

MySQL中MVCC的流程

参考文章一 参考文章二 当谈到数据库的并发控制时&#xff0c;多版本并发控制&#xff08;MVCC&#xff09;是一个重要的概念。MVCC 是一种用于实现数据库事务隔离性的技术&#xff0c;常见于像 PostgreSQL 和 Oracle 这样的数据库系统中。 MVCC 的核心思想是为每个数据行维护…