用C#实现MVC+观察者模式(WINFORM)

2023-05-16

用C#实现MVC(Model View Control)模式介绍

益处

下载案例:https://download.csdn.net/download/gigizhongyan/13011332

    在我们的开发项目中使用MVC(Model-View-Control)模式的益处是,可以完全降低业务层和应用表示层的相互影响。此外,我们会有完全独立的对象来操作表示层。MVC在我们项目中提供的这种对象和层之间的独立,将使我们的维护变得更简单使我们的代码重用变得很容易(下面你将看到)。

作为一般的习惯,我们知道我们希望保持最低的对象间的依赖,这样变化能够很容易的得到满足,而且我们可以重复使用我们辛辛苦苦写的代码。为了达到这个目的我们将遵循一般的原则“对接口编成,而不是对类”来使用MVC模式。

我们的构架概要

好,现在我们知道我们要使用MVC,我们需要指出它的本质。通过我们的试验得出MVC的三个部分:Model,Control和View。在我们的系统中,Model就是我们的汽车,View就是我们的画面,Control将这两个部分联系起来。

uploading.4e448015.gif正在上传…重新上传取消

为了改变Model(我们的ACME 2000 sports car),我们需要使用Control。我们的Control将会产生给Model(我们的ACME 2000 sports car)的请求,和更新View,View就是我们的画面(UI)。

这看起来很简单,但是这里产生了第一个要解决的问题:当终端用户想做一个对ACME 2000 sports car一个改变将会发生什么,比如说加速或是转向?他们将通过View(our windows form)用Control来提出一个变化的申请。

uploading.4e448015.gif正在上传…重新上传取消

现在我们就剩下一个未解决问题了。如果View没有必要的信息来显示Model的状态怎么办?我们需要再在我们的图中加入一个箭头:View将能申请Model的状态以便得到它要显示的相关状态信息。

uploading.4e448015.gif正在上传…重新上传取消

最后,我们的最终用户(司机)将会和我们的ACME Vehicle Control系统通过View来交互。如果他们想发出一个改变系统的申请,比如提高一点加速度,申请将会从View开始发出由Control处理。

Control将会向Model申请改变并将必要的变化反映在View上。比如,如果一个蛮横的司机对ACME 2000 Sports Car做了一个"floor it"申请,而现在行驶的太快不能转向,那么Control将会拒绝这个申请并在View中通知,这样就防止了在交通拥挤是发生悲惨的连环相撞。

Model (the ACME 2000 Sports Car) 将通知View 它的速度已经提高,而View也将做适当的更新。

综上,这就是我们将构建的概要:

uploading.4e448015.gif正在上传…重新上传取消

首先,我们考虑一下基本的项目。我们需要一些东西来表示方向和转动请求。我们做了两个枚举类型:AbsoluteDirection 和 RelativeDirection

public enum AbsoluteDirection

{

North=0, East, South, West

}

public enum RelativeDirection

{

Right, Left, Back

}

下面来解决Control接口。我们知道Control需要将请求传递给Model,这些请求包括:Accelerate, Decelerate, 和 Turn。我们建立一个IVehicleControl接口,并加入适当的方法。

public interface IVehicleControl

{

void Accelerate(int paramAmount);

void Decelerate(int paramAmount);

void Turn(RelativeDirection paramDirection);

}

现在我们来整理Model接口。我们需要知道汽车的名字,速度,最大速度,最大倒退速度,最大转弯速度和方向。我们也需要加速,减速,转弯的函数。

public interface IVehicleModel

{

string Name{ get; set;}

int Speed{ get; set;}

int MaxSpeed{ get;}

int MaxTurnSpeed{ get;}

int MaxReverseSpeed { get;}

AbsoluteDirection Direction{get; set;}

void Turn(RelativeDirection paramDirection);

void Accelerate(int paramAmount);

void Decelerate(int paramAmount);

}

最后,我们来整理View接口。我们知道View需要暴露出Control的一些机能,比如允许或禁止加速,减速和转弯申请。

public interface IVehicleView

{

void DisableAcceleration();

void EnableAcceleration();

void DisableDeceleration();

void EnableDeceleration();

void DisableTurning();

void EnableTurning();

}

现在我们需要做一些微调使我们的这些接口能够互相作用。首先,任何一个Control都需要知道它的View和Model,所以在我们的IvehicleControl接口中加入两个函数:"SetModel" 和"SetView":

public interface IVehicleControl

{

void RequestAccelerate(int paramAmount);

void RequestDecelerate(int paramAmount);

void RequestTurn(RelativeDirection paramDirection);

void SetModel(IVehicleModel paramAuto);

void SetView(IVehicleView paramView);

}

下一个部分比较巧妙。我们希望View知道Model中的变化。为了达到这个目的,我们使用观察者模式。

为了实施观察者模式,我们需要将下面的函数加入到Model(被View观察):AddObserver, RemoveObserver, 和 NotifyObservers。

 

public interface IVehicleModel

{

string Name{ get; set;}

int Speed{ get; set;}

int MaxSpeed{ get;}

int MaxTurnSpeed{ get;}

int MaxReverseSpeed { get;}

AbsoluteDirection Direction{get; set;}

void Turn(RelativeDirection paramDirection);

void Accelerate(int paramAmount);

void Decelerate(int paramAmount);

void AddObserver(IVehicleView paramView);

void RemoveObserver(IVehicleView paramView);

void NotifyObservers();

}

并且将下面的函数加入到View(被Model观察)中。这样做的目的是Model会有一个View的引用。当Model发生变化时,将会调用NotifyObservers()方法,传入一个对其自身的引用并调用Update()通知View这个变化。

public class IVehicleView

{

void DisableAcceleration();

void EnableAcceleration();

void DisableDeceleration();

void EnableDeceleration();

void DisableTurning();

void EnableTurning();

void Update(IVehicleModel paramModel);

}

这样我们就将我们的接口联系起来了。在下面的代码中我们只需要引用我们这些接口,这样就保证了我们代码的低耦合。任何显示汽车状态的用户界面都需要实现IVehicleView,我们所有的ACME都需要实现IVehicleModel,并且我们需要为我们的ACME汽车制作Controls,这些Control将实现IVehicleControl接口。

我们知道所有的汽车都做相同的动作,所以我们接下来做一个基于“骨架”的共有的代码来处理这些操作。这是一个抽象类,因为我们不希望任何人在“骨架”上开车(抽象类是不能被实例化的)。我们称其为Automobile。我们将用一个ArrayList (from System.Collections)来保持跟踪所有感兴趣的Views(记住观察者模式了吗?)。我们也可以用老式的数组来记录对IVehicleView的引用,但是现在我们已经很累了想快点结束这篇文章。如果你感兴趣,看一下在观察者模式中AddObserver, RemoveObserver, 和NotifyObservers,这些函数是怎样和IVehicleView互相作用的。任何时间当有速度或方向变化时,Automobile通知所有的IVehicleViews。

 

public abstract class Automobile: IVehicleModel

{

"Declarations "#region "Declarations "

private ArrayList aList = new ArrayList();

private int mintSpeed = 0;

private int mintMaxSpeed = 0;

private int mintMaxTurnSpeed = 0;

private int mintMaxReverseSpeed = 0;

private AbsoluteDirection mDirection = AbsoluteDirection.North;

private string mstrName = "";

#endregion

"Constructor"#region "Constructor"

public Automobile(int paramMaxSpeed, int paramMaxTurnSpeed, int paramMaxReverseSpeed, string paramName)

{

this.mintMaxSpeed = paramMaxSpeed;

this.mintMaxTurnSpeed = paramMaxTurnSpeed;

this.mintMaxReverseSpeed = paramMaxReverseSpeed;

this.mstrName = paramName;

}

#endregion

"IVehicleModel Members"#region "IVehicleModel Members"

public void AddObserver(IVehicleView paramView)

{

aList.Add(paramView);

}

public void RemoveObserver(IVehicleView paramView)

{

aList.Remove(paramView);

}

public void NotifyObservers()

{

foreach(IVehicleView view in aList)

{

view.Update(this);

}

}

public string Name

{

get

{

return this.mstrName;

}

set

{

this.mstrName = value;

}

}

public int Speed

{

get

{

return this.mintSpeed;

}

}

public int MaxSpeed

{

get

{

return this.mintMaxSpeed;

}

}

public int MaxTurnSpeed

{

get

{

return this.mintMaxTurnSpeed;

}

}

public int MaxReverseSpeed

{

get

{

return this.mintMaxReverseSpeed;

}

}

public AbsoluteDirection Direction

{

get

{

return this.mDirection;

}

}

public void Turn(RelativeDirection paramDirection)

{

AbsoluteDirection newDirection;

switch(paramDirection)

{

case RelativeDirection.Right:

newDirection = (AbsoluteDirection)((int)(this.mDirection + 1) %4);

break;

case RelativeDirection.Left:

newDirection = (AbsoluteDirection)((int)(this.mDirection + 3) %4);

break;

case RelativeDirection.Back:

newDirection = (AbsoluteDirection)((int)(this.mDirection + 2) %4);

break;

default:

newDirection = AbsoluteDirection.North;

break;

}

this.mDirection = newDirection;

this.NotifyObservers();

}

public void Accelerate(int paramAmount)

{

this.mintSpeed += paramAmount;

if(mintSpeed >= this.mintMaxSpeed) mintSpeed = mintMaxSpeed;

this.NotifyObservers();

}

public void Decelerate(int paramAmount)

{

this.mintSpeed -= paramAmount;

if(mintSpeed <= this.mintMaxReverseSpeed) mintSpeed = mintMaxReverseSpeed;

this.NotifyObservers();

}

#endregion

}

最后但不是至少

现在我们的"ACME Framework"已经做好了,我们只需要设立有形的类和接口。首先让我们看看最后两个类:Control 和 Model...

这里我们有形的AutomobileControl实现IVehicleControl接口。我们的AutomobileControl也将设置View来依赖Model 的状态

注意,我们只是有对IVehicleModel的引用(而不是抽象类Automobile )和对IVehicleView的引用(而不是具体的View),这样保证对象间的低耦合。

 

public class AutomobileControl: IVehicleControl

{

private IVehicleModel Model;

private IVehicleView View;

public AutomobileControl(IVehicleModel paramModel, IVehicleView paramView)

{

this.Model = paramModel;

this.View = paramView;

}

public AutomobileControl()

{

}

IVehicleControl Members#region IVehicleControl Members

public void SetModel(IVehicleModel paramModel)

{

this.Model = paramModel;

}

public void SetView(IVehicleView paramView)

{

this.View = paramView;

}

public void RequestAccelerate(int paramAmount)

{

if(Model != null)

{

Model.Accelerate(paramAmount);

if(View != null) SetView();

}

}

public void RequestDecelerate(int paramAmount)

{

if(Model != null)

{

Model.Decelerate(paramAmount);

if(View != null) SetView();

}

}

public void RequestTurn(RelativeDirection paramDirection)

{

if(Model != null)

{

Model.Turn(paramDirection);

if(View != null) SetView();

}

}

#endregion

public void SetView()

{

if(Model.Speed >= Model.MaxSpeed)

{

View.DisableAcceleration();

View.EnableDeceleration();

}

else if(Model.Speed <= Model.MaxReverseSpeed)

{

View.DisableDeceleration();

View.EnableAcceleration();

}

else

{

View.EnableAcceleration();

View.EnableDeceleration();

}

if(Model.Speed >= Model.MaxTurnSpeed)

{

View.DisableTurning();

}

else

{

View.EnableTurning();

}

}

}

现在轮到我们的View了...

现在终于开始建立我们MVC最后一个部分了...View!

我们要建立一个AutoView来实现IVehicleView接口。这个AutoView将会有对Control和Model接口的引用。

public class AutoView : System.Windows.Forms.UserControl, IVehicleView

{

private IVehicleControl Control = new ACME.AutomobileControl();

private IVehicleModel Model = new ACME.ACME2000SportsCar("Speedy");

}

我们也需要将所有的东西包装在UserControl的构造函数中。

public AutoView()

{

// This call is required by the Windows.Forms Form Designer.

InitializeComponent();

WireUp(Control, Model);

}

public void WireUp(IVehicleControl paramControl, IVehicleModel paramModel)

{

// If we're switching Models, don't keep watching

// the old one!

if(Model != null)

{

Model.RemoveObserver(this);

}

Model = paramModel;

Control = paramControl;

Control.SetModel(Model);

Control.SetView(this);

Model.AddObserver(this);

}

private void btnAccelerate_Click(object sender, System.EventArgs e)

{

Control.RequestAccelerate(int.Parse(this.txtAmount.Text));

}

private void btnDecelerate_Click(object sender, System.EventArgs e)

{

Control.RequestDecelerate(int.Parse(this.txtAmount.Text));

}

private void btnLeft_Click(object sender, System.EventArgs e)

{

Control.RequestTurn(RelativeDirection.Left);

}

private void btnRight_Click(object sender, System.EventArgs e)

{

Control.RequestTurn(RelativeDirection.Right);

}

public void UpdateInterface(IVehicleModel auto)

{

this.label1.Text = auto.Name + " heading " + auto.Direction.ToString() + " at speed: " + auto.Speed.ToString();

this.pBar.Value = (auto.Speed>0)? auto.Speed*100/auto.MaxSpeed : auto.Speed*100/auto.MaxReverseSpeed;

}

 

public void DisableAcceleration()

{

this.btnAccelerate.Enabled = false;

}

public void EnableAcceleration()

{

this.btnAccelerate.Enabled = true;

}

public void DisableDeceleration()

{

this.btnDecelerate.Enabled = false;

}

public void EnableDeceleration()

{

this.btnDecelerate.Enabled = true;

}

public void DisableTurning()

{

this.btnRight.Enabled = this.btnLeft.Enabled = false;

}

public void EnableTurning()

{

this.btnRight.Enabled = this.btnLeft.Enabled = true;

}

public void Update(IVehicleModel paramModel)

{

this.UpdateInterface(paramModel);

}

 

幸运的是我们用的是MVC!我们需要做的所有工作就是建立一个新的ACMETruck类,包装一下,完事!

 

public class ACME2000Truck: Automobile

{

public ACME2000Truck(string paramName):base(80, 25, -12, paramName){}

public ACME2000Truck(string paramName, int paramMaxSpeed, int paramMaxTurnSpeed, int paramMaxReverseSpeed):

base(paramMaxSpeed, paramMaxTurnSpeed, paramMaxReverseSpeed, paramName){}

}

在AutoView中,我们只需要建立卡车包装一下!

private void btnBuildNew_Click(object sender, System.EventArgs e)

{

this.autoView1.WireUp(new ACME.AutomobileControl(), new ACME.ACME2000Truck(this.txtName.Text));

}

如果我们想要一个新Control只允许我们来每次加速或减速最大5mph,小意思!做一个SlowPokeControl(和我们的AutoControl相同,但是在申请加速度中做了限制)。

public void RequestAccelerate(int paramAmount)

{

if(Model != null)

{

int amount = paramAmount;

if(amount > 5) amount = 5;

Model.Accelerate(amount);

if(View != null) SetView();

}

}

public void RequestDecelerate(int paramAmount)

{

if(Model != null)

{

int amount = paramAmount;

if(amount > 5) amount = 5;

Model.Accelerate(amount);

Model.Decelerate(amount);

if(View != null) SetView();

}

}

如果我们想让我们的ACME2000 Truck变得迟钝,只需要在AutoView中包装。

private void btnBuildNew_Click(object sender, System.EventArgs e)

{

this.autoView1.WireUp(new ACME.SlowPokeControl(), new ACME.ACME2000Truck(this.txtName.Text));

}

最后,如果我们需要一个在web上的接口,我们要做的所有工作就是建立一个Web项目在UserControl中实现IVehicleView接口。

结论

正如你所看到的,使用MVC来构建代码控制接口耦合性很低,很容易适应需求的改变。它也能使变化的影响减小,而且你可以在任何地方重用你的虚函数和接口。有很多时候我们可以在我们的项目中实现伸缩性,特别是在那些需求变化的时候,但是这需要下次再说了。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用C#实现MVC+观察者模式(WINFORM) 的相关文章

  • 【githubshare】KCon 黑客大会演讲 macOS Big Sur 内核漏洞挖掘、云虚拟化安全、服务器硬件可信与安全实践

    GitHub 上一个开源资料库 KCon 黑客大会演讲 PPT 2021 年包含了 macOS Big Sur 内核漏洞挖掘 云虚拟化安全 服务器硬件可信与安全实践等内容 个开源资料库 KCon 黑客大会演讲 PPT 2021 年包含了 m
  • MVC知识整理

    MVC基础知识整理 ASP NETMVC框架 这里以MVC5为例 涉及到知识有 Model View Controller的使用 Area和Global的理解 路由配置 数据传递的方式 AOP思想的体现 4大过滤器 各种Result Raz
  • MVC 向页面传值方式总结

    总结发现ASP NET MVC中Controller向View传值的方式共有6种 分别是 ViewBag ViewData TempData 向普通View页面传一个Model对象 向强类型页面传传一个Model对象 用一个ViewMode
  • Android面试题——javaMVC、AndroidMVC

    中的 模型 对象 是应用程序的主体部分 多有业务逻辑都应该放到该层 视图 对象 是应用程序中负责生成用户界面的部分 也是整个 架构中用户唯一可以看到的一层 接受用户的输入 显示处理结果 3 控制器 controller 对象 是根据用户的输
  • 07.JavaWeb-Vue+elementUI

    1 Vue 功能替代JavaScript和jQuery 基于JavaScript实现的前端框架 1 1配置Vue 1 1 1引入vue库 方法一 通过cdn链接引入最新版本的vue 可能会慢些 方法二 将vue库下载到本地 通过相对路径引入
  • JSP&EL表达式&MVC&三层结构综合案例

    文章目录 JSP 1 JSP 概述 2 JSP 快速入门 2 1 搭建环境 2 2 导入 JSP 依赖 2 3 创建 jsp 页面 2 4 编写代码 2 5 测试 3 JSP 原理 4 JSP 脚本 4 1 JSP 脚本分类 4 2 案例
  • springmvc框架

    1 什么是MVC MVC就是一个分层架构模式 M即model模型是指模型表示业务规则 在MVC的三个部件中 模型拥有最多的处理任务 被模型返回的数据是中立的 模型与数据格式无关 这样一个模型能为多个视图提供数据 由于应用于模型的代码只需写一
  • SSM框架---springMVC

    目录 一 概述 分层思想 二 工作原理 1 导入jar包 2 创建启动类 三 处理请求参数 3 1 get方式 3 2 post方式 3 3 restful方式 推荐 四 处理get 请求的参数 五 处理post请求的参数 六 处理rest
  • mybatis的熟练运用以及反射知识讲解

    JSP常用设计模式MVC模式 Mybatis mybatis的使用 我们在写项目的时候必定要写DAO 写DAO的时候不难发现对每张表的DAO都差不多 只是sql语句不同 DAO中的每个方法其实也差不多 所以直接用JDBC写DAO是在太麻烦
  • 【WinForm】WebView2-个性化浏览器-桌面程序开发详解

    这是一个桌面程序上的浏览器 是用插件WebView2开发的浏览器桌面程序 功能体验堪比Edge浏览器 相比使用Chrome内核插件开发浏览器来说 还是用插件WebView2开发来得简单一些 接下来讲一讲实现过程 开发之前 建议先看看微软的
  • 【JavaWeb】Thymeleaf的简介与使用

    Thmeleaf MVC 为什么需要MVC 我们之前在书城项目第二阶段做登录的时候 曾经提出过优化登录失败后的处理 虽然说可以实现在登录失败之后跳转回到登录页面 并且展示失败信息 但是代码实在是太恶心了 根本没法维护 所以我们需要将视图展示
  • MVVM框架极简总结

    MVVM是一个前端框架 由model view viewmodel组成 是MVC的升级版 变成了由viewmodel进行m和v之间的双向数据绑定 虽然代码量相较于MVC变得更多了一点 逻辑和视图分开来写 但是更利于代码解耦 也更方便测试来自
  • 利用MVC做一个 常见的管理系统

    登陆的部分 gt 数据库 gt 表 admin id name pass regtime 表与类的映射关系 基于面向对象 转换成对象的操作 gt 登陆页面
  • cpp: Observer Pattern

    Gold h 此文件包含 Gold 类 Observer Pattern 观察者模式 C 14 Jewelry Observer Pattern 观察者模式 2023年5月10日 涂聚文 Geovin Du Visual Studio 20
  • angular中的全局方法和指令介绍1

    复习并总结Angular开发流程 0 下载angular 暴力angular 找到js拖拽过来 npm下载 1 引入 2 在要控制的标签上写上ng app 3 写controller 告诉angular哪部分dom结构有哪个controll
  • 基于SpringBoot的图书管理系统

    基于SpringBoot的图书管理系统 里面整合了比较全的内容 可以说是麻雀虽小五脏俱全 如果看懂了所有的内容可以说是已经非常精通SpringBoot了 一 引言 由于近期看了SpringBoot 一站式开发特别方便 情不自禁用Spring
  • MVC三层架构

    1 什么是MVC Model View Controller 模型 视图 控制器 模型就是Java对应数据库的那些字段 实体类 视图 就是JSP页面 控制器 就是Servlet负责跳转页面 Controller作用 Controller其实
  • html理解MVC模型与MVVM模型底层实现

    一 MVC模型的底层实现 1 1 相关代码 div div
  • MVC三层架构

    1 MVC三层架构 MVC Model View Controller 是一种常见的软件设计模式 用于组织和管理应用程序的代码和逻辑 它将应用程序分为三个主要部分 模型 Model 视图 View 和控制器 Controller 每个部分都
  • Spring MVC开发流程

    1 Spring MVC环境基本配置 Maven工程依赖spring webmvc

随机推荐

  • word中插入一页横向页面

    参考 xff1a https zhidao baidu com question 7650080 html 有时需要在竖版的页面中插入一个横向页面的大表格 大图片等 xff0c 不能直接修改纸张方向 xff0c 因为在Word中 xff0c
  • 手动控制DELL服务器风扇转速

    参考 xff1a https www cnblogs com dreamdale p 13187452 html https www cnblogs com lothar p 13321205 html https www cnblogs
  • 通过windows日志查看器查看系统登陆日志

    起因 xff1a 回到工位发现自己电脑没锁屏 xff0c 突然想找到查看windows登录记录的方法 参考 xff1a http www cflab net News 1522379153901 https blog csdn net C
  • hackrf+portapack 组装上手体验记录

    1 物理安装 拧下SMA天线接头 用portapack提供的黄色翘片撬开hackrf盖子 插接两块板子 装好螺丝和sma天线接头的垫片和螺母即可 2 更新固件 装好后需要更新固件 xff0c 否则portapack插好电后只闪一下 xff0
  • ios平台Ahorro记账APP换新机无法下载问题

    起因 xff1a 更换iphone新机后 xff0c 原有记账APP Ahorro在app store中已不再提供 xff0c 无法下载 解决方法 xff1a 前提 xff1a 原有手机仍在手上 xff0c 且原有手机中的Ahorro AP
  • Microsoft Print to PDF的纸张大小问题

    问题 尚未解决 在word打印选项页面设置纸张大小为信纸 xff0c 在 打印机属性 gt 高级 中也设置纸张规格为信纸 但是导出的PDF文档大小依然是A4 猜想原因 在打印机的可用纸张选项中只有A4 xff0c 且未找到添加纸张类型的方法
  • KDE下安装Fcitx

    sudo apt get install fcitx pinyin im switch im switch s fcitx z all ALL 修改 etc X11 xinit xinput d fcitx xff0c 为 xff1a XI
  • win10 vs2015 tesseract5.0

    https www cnblogs com hupeng1234 p 8545371 html
  • python 买卖提的菜单_03

    temp 61 input 34 你要买几根 xff1f n 34 mount 61 int temp print type temp Totalprice 61 20 mount print 39 您一共需要支付 xff1a 39 43
  • python 02

    import turtle as t 39 39 39 t speed 0 t screensize 600 500 屏幕大小 t pensize 5 t pencolor 34 black 34 t fillcolor 34 black
  • 取字符串某个特定字符后的字符串 strchr函数

    strchr函数返回指定字符串中从左到右第一个指定字符的指针 xff0c 未找到则返回NULL 函数原型 xff1a extern char strchr char str char character 例如 xff1a 字符串s为 11
  • 折腾了好久这个opencv的Windows库

    折腾了好久这个opencv的Windows库 xff0c 实在是想吐血了 终于找到一个可以用的已经编译好的 xff0c 下载地址如下 xff1a https github com huihut OpenCV MinGW Build 来自 x
  • ch10_列表 字典 例子

    num 61 num len 61 0 for i in range 100 if i gt 1 temp 61 0 for j in range 2 int i 2 if i j 61 61 0 temp 43 61 1 if temp
  • C# AForge设置摄像头参数(含代码)

    网上有很多c 设置摄像头参数的例子 xff0c 代码给的不多 增加新类的源码 xff1a AForge设置摄像头参数实例源码 源码地址 xff1a https download csdn net download gigizhongyan
  • QT 开发多窗口多页面问题(一)中文乱码的问题

    开发环境 xff1a Microsoft Visual C 43 43 2019 43 QT 5 13 1 QT5 中文乱码 xff0c 网上有很多例子 效果有但是没有那么彻底 因为我需要使用tr 后续中文需要翻译 最后在 h文件中加入了
  • QT 开发多窗口多页面问题(二)QT 插件模式

    编译环境 xff1a VS2019 43 QT5 13 1 业务要求 xff1a 界面是多窗口拖动的模式 xff0c 窗口采用插件的模式 xff08 DLL xff09 封装 参考的文档 xff1a 结合两个文档 结合了vs的QDesign
  • QT项目适配libmodbus3.1.6库源码

    想要自己开发的可以参考 xff1a https blog csdn net qq 37887537 article details 88548358 https blog csdn net zgrjkflmkyc article detai
  • 时隔一年,C++加python 的混合编程(包括python无环境发布)

    时隔一年 xff0c 上一篇文档比较LOW一点 xff0c 实现了python2 7的混合编译 xff0c 可发布无PYTHON环境的机器 发布也是比较LOW xff0c 文件特别大 编译版本 xff1a python 3 7 2 xff0
  • 逆向APP查看内部源码

    我的原创 xff1a https www jianshu com p 991265039648 文章中使用的工具 xff1a https download csdn net download gigizhongyan 12568942
  • 用C#实现MVC+观察者模式(WINFORM)

    用C 实现MVC xff08 Model View Control xff09 模式介绍 益处 下载案例 xff1a https download csdn net download gigizhongyan 13011332 在我们的开发