using MaiMuAOI.ImageProcessing; using MaiMuAOI.SysCtrl; using MaiMuAOI.SysUI.DefectPicShow; using MaiMuAOI.SysUI.SysSet; using MaiMuControl.Utils; using Newtonsoft.Json; using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using static MaiMuAOI.ImageProcessing.DefectLib; namespace ProductionControl.UI { public partial class UIDefectLib : UserControl { SynchronizationContext SyncContext = null; public Action GetParamsEvent; // private DefectLibProp prop = new DefectLibProp(ConfMgr.Instance.SysConfigParams.Defect_CutSize, ConfMgr.Instance.SysConfigParams.Defect_ReSize, ConfMgr.Instance.SysConfigParams.Defect_Thresholds); private DefectLib _dev; public UIDefectLib(DefectLib dev) { InitializeComponent(); _dev = dev; propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged; refreshUIState(); //获取UI线程同步上下文 SyncContext = SynchronizationContext.Current; //init(); } private string szLog; private void refreshUIState() { foreach (ToolStripItem item in this.toolStrip1.Items) { if (item.Text == "打开设备") item.Visible = (_dev == null || !_dev.IsInit); else this.propertyGrid1.Enabled = item.Enabled = !(_dev == null || !_dev.IsInit); } } public void init() { this.tbtnSave.Visible = tssSave.Visible = (GetParamsEvent != null); this.propertyGrid1.SelectedObject = prop; //_dev = new DefectLib(); _dev.WarningEvent = (level, info) => { szLog = $"({level}){info}"; txtLog.Text = $"({level}){info}"; }; //DATA _dev.finishEvent += new System.Action((task) => { DateTime t1= DateTime.Now; var t2=t1-task.nowTime; var t3= t2.Milliseconds; prop.InformationList = JsonConvert.SerializeObject(task.informationList); prop.resultInfo = task.isSucceed ? "成功" : task.resultInfo; this.refreshUI(); }); //if (!_dev.start()) //{ // this.closeDev(); // return; //} //string onnxFile = $"{Application.StartupPath}\\onnxFiles\\default.onnx"; string onnxFile = $"{ConfMgr.Instance.SysConfigParams.AIModelPath}\\default.onnx"; _dev.loadModelFile(onnxFile); refreshUIState(); } public string getParamsData() { return prop.serialize(); } public void setParamsData(string json) { if (json == "") return; prop.deserialize(json); this.propertyGrid1.Refresh(); } private void refreshUI() { SyncContext.Post(m => { var result = m as string; propertyGrid1.Refresh(); //txtLog.Text = szLog;//不显示 //tbtnJogOnOff.Text = (prop.AxState == AxisState.STA_AX_EXT_JOG) ? "关闭Jog" : "开启Jog"; //tbtnLeft.Enabled = tbtnRight.Enabled = (prop.AxState == AxisState.STA_AX_EXT_JOG); }, "异步操作完成结果"); } private void closeDev() { //try //{ // if (_dev == null) // return; // _dev.stop(); //} //catch (Exception ex) //{ // refreshUIState(); // MessageBox.Show(ex.Message, "失败", MessageBoxButtons.OK, MessageBoxIcon.Error); //} } protected override void OnHandleDestroyed(EventArgs e) { base.OnHandleDestroyed(e); // 在此添加需要手动释放资源的代码 this.closeDev(); if(frm !=null) frm.Close(); } private void tbtnRun_Click(object sender, EventArgs e) { if (!Util.IsNumber(prop.ThresholdsClass.Replace("-", "").Replace(",", "").Replace(";", "").Replace(".", ""))) { txtLog.Text = "种类阀值只可输入数字!"; return; } if (!verifyThresholdsCount(prop.ThresholdsClass, prop.ThresholdsClassCount)) { txtLog.Text = "输入种类阀值与数量不一致!"; return; } try { _dev.loadModelFile(prop.ModelPath); prop.resultInfo = ""; _dev.add(new DefectTask() { nowTime= DateTime.Now, bmp=new Mat(prop.BmpPath), cut_size=prop.CutSize, resize=prop.Resize, thresholds=prop.Thresholds, thresholdsClass = prop.ThresholdsClass, //finishEvent = (res) => //{ //} }); } catch(Exception ex) { MessageBox.Show(ex.Message, "失败", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void tbtnExport_Click(object sender, EventArgs e) { string filePath = ConfMgr.SaveAsFile($"DefectLib Config.json", "JSON|*.json"); if (filePath != "") { string jsonText = prop.serialize(); File.WriteAllText(filePath, jsonText); MessageBox.Show("保存成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void tbtnImport_Click(object sender, EventArgs e) { string filePath = ConfMgr.SelectFile("JSON|*.json"); if (filePath != "") { string jsonText = File.ReadAllText(filePath); prop.deserialize(jsonText); this.propertyGrid1.Refresh(); //this.propertyGrid1.SelectedObject= prop; //MessageBox.Show("加载成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { //其中包含了两个重要的属性:OldValue和ChangeItem。 //ChangeItem是“PropertyDescriptorGridEntry”类型。一般可以通过ChangeItem.PropertyDescriptor.ComponentType查找到属性的实际类型。 //而通过ChangeItem的Label,则可以查看到当前在属性编辑输入框中显示的值。 string className = e.ChangedItem.PropertyDescriptor.ComponentType.Name; string propertyName = e.ChangedItem.PropertyDescriptor.Name; var oldValue = e.OldValue; var newValue = e.ChangedItem.Value; switch (propertyName) { case "ThresholdsClass": if(!Util.IsNumber(newValue.ToString().Replace("-","").Replace(",", "").Replace(";", "").Replace(".", ""))) txtLog.Text = "种类阀值只可输入数字!"; else if (!verifyThresholdsCount(newValue.ToString(), prop.ThresholdsClassCount)) txtLog.Text = "输入种类阀值与数量不一致!"; else txtLog.Text = ""; break; case "ThresholdsClassCount": if (!verifyThresholdsCount(prop.ThresholdsClass, (int)newValue)) txtLog.Text = "输入种类阀值与数量不一致!"; else txtLog.Text = ""; break; } } private void tbtnSave_Click(object sender, EventArgs e) { if (!Util.IsNumber(prop.ThresholdsClass.Replace("-", "").Replace(",", "").Replace(";", "").Replace(".", ""))) { txtLog.Text = "种类阀值只可输入数字!"; return; } if (!verifyThresholdsCount(prop.ThresholdsClass, prop.ThresholdsClassCount)) { txtLog.Text = "输入种类阀值与数量不一致!"; return; } GetParamsEvent?.Invoke(prop.serialize()); } private void tsbtnOpenDev_Click(object sender, EventArgs e) { szLog = txtLog.Text = ""; this.init(); } private bool verifyThresholdsCount(string szThresholdsClass,int iThresholdsClassCount) { return szThresholdsClass.Trim().TrimEnd(new char[] { ',', ';' }) .Split(new char[] { ',', ';' }).Count() == iThresholdsClassCount; } DebugTestFrm frm; private void tsbDebug_Click(object sender, EventArgs e) { if ((frm == null) || (frm.IsDisposed)) frm = new DebugTestFrm(); frm.TopMost = true; frm.Show(); } } }