有经验的初次上手,直接教程区参考就行,代码区的就是详细过程了


文章目录

  • 教程区
  • 代码区
  • 2/4 第一版
  • 2/8 更新
  • 2/21更新


教程区

程序会不断完善成项目
文末有初学第一次写的代码

首先添加TCADSDLL.DLL文件到python安装目录下

python连接AB的PLC读取数据_python


添加pyads库,就可以直接读取和写入值啦

python连接AB的PLC读取数据_回调函数_02


这里有控制器的NETID,倍福默认ADS端口为851

python连接AB的PLC读取数据_python连接AB的PLC读取数据_03


这里有变量的地址

python连接AB的PLC读取数据_sed_04


附加一张写入和读取成功的图,在倍福控制系统里,0也可以=FALSE,1=TRUE

python连接AB的PLC读取数据_python连接AB的PLC读取数据_05


效果图:

python连接AB的PLC读取数据_回调函数_06


python连接AB的PLC读取数据_python_07


GUI库用的是wxpython(目前感觉不是很好用,接下来可能会采用qt)

附加库的下载地址以及使用方法:

https://pypi.org/project/pyads/

很菜,将就着看吧,会不断更新完善的

代码区

2/4 第一版

import pyads
import wx
import time

plc = pyads.Connection('169.254.254.110.1.1', 851)
def plc_connact():
    plc.open()
plc_connact()

class HelloFrame(wx.Frame):
    ClickNum = 0  # 定义变量
    ClickNum1 = 0  # 定义变量
    ClickNum2 = 0  # 定义变量

    """
    A Frame that says Hello World
    """

    def __init__(self, *args, **kw):
        # ensure the parent's __init__ is called
        super(HelloFrame, self).__init__(*args, **kw)

        self.icon1 = wx.Icon(name="wx.jpg", type=wx.BITMAP_TYPE_ANY)
        self.SetIcon(self.icon1)

        # create a panel in the frame
        pnl = wx.Panel(self)

        # create a Button
        self.b = wx.Button(pnl, -1, "测试启动", pos=(0, 0))
        self.Bind(wx.EVT_BUTTON, self.OnClick, self.b)

        self.c = wx.Button(pnl, -1, "启动_ON", pos=(0, 30))
        self.c.Bind(wx.EVT_LEFT_DOWN, self.OnClick1)
        self.c.Bind(wx.EVT_LEFT_UP, self.OnClick3)

        self.d = wx.Button(pnl, -1, "停止_ON", pos=(0, 60))
        self.d.Bind(wx.EVT_LEFT_DOWN, self.OnClick2)
        self.d.Bind(wx.EVT_LEFT_UP, self.OnClick4)

        self.e = wx.Button(pnl, -1, "", pos=(0, 90))        #工位状态
        self.e.Bind(wx.EVT_LEFT_UP, self.OnClick5)

        if plc.read_by_name('MAIN.B', pyads.PLCTYPE_BOOL):
            self.e.SetLabel("工位有料")  # 设置按钮标签
        else:
            self.e.SetLabel("工位无料")  # 设置按钮标签

        # create a menu bar
        self.makeMenuBar()
        # and a status bar
        self.CreateStatusBar()
        self.SetStatusText("Welcome to CC!")

    def OnClick(self, event):  # 回调函数事件
        #self.b.SetLabel("测试关闭")  # 设置
        self.ClickNum += 1

        try:
            if self.ClickNum % 2 == 1:  # 根据按下次数判断
                self.b.SetLabel("测试关闭")  # 修改按键的标签
                plc.write_by_name('MAIN.A', True, pyads.PLCTYPE_BOOL)
                Start = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
                print(Start)
                print(self.b.GetLabel())  # 打印信息(返回按键的标签信息)
                # print(self.ClickNum)
            # elif self.ClickNum % 2 == 3:
            else:
                # time.sleep(0.1)
                self.b.SetLabel("测试启动")
                plc.write_by_name('MAIN.A', False, pyads.PLCTYPE_BOOL)
                Start = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
                print(Start)
                self.ClickNum = 0
                print(self.b.GetLabel())
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

    def OnClick1(self, event):
        self.c.SetLabel("启动_OFF")  # 修改按键的标签

        try:
            plc.write_by_name('MAIN.A', True, pyads.PLCTYPE_BOOL)
            Start1 = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
            print(Start1)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.c.GetLabel())  # 打印信息(返回按键的标签信息)
        event.Skip()

    def OnClick3(self, event):
        self.c.SetLabel("启动_ON")  # 修改按键的标签

        try:
            plc.write_by_name('MAIN.A', False, pyads.PLCTYPE_BOOL)
            Start1 = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
            print(Start1)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.c.GetLabel())  # 打印信息(返回按键的标签信息)
        event.Skip()

    def OnClick2(self, event):  # 回调函数事件
        self.d.SetLabel("停止_OFF")  # 设置

        try:
            plc.write_by_name('information.rest_all', True, pyads.PLCTYPE_BOOL)
            Start2 = plc.read_by_name('information.rest_all', pyads.PLCTYPE_BOOL)
            print(Start2)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.d.GetLabel())  # 打印信息(返回按键的标签信息)

    def OnClick4(self, event):  # 回调函数事件
        self.d.SetLabel("停止_ON")  # 设置

        try:
            plc.write_by_name('information.rest_all', False, pyads.PLCTYPE_BOOL)
            Start2 = plc.read_by_name('information.rest_all', pyads.PLCTYPE_BOOL)
            print(Start2)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.d.GetLabel())  # 打印信息(返回按键的标签信息)

    def OnClick5(self, event):  # 回调函数事件

        try:
            plc.write_by_name('information.rest_all', False, pyads.PLCTYPE_BOOL)
            Start2 = plc.read_by_name('information.rest_all', pyads.PLCTYPE_BOOL)
            print(Start2)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.d.GetLabel())  # 打印信息(返回按键的标签信息)


    def makeMenuBar(self):
        """
        A menu bar is composed of menus, which are composed of menu items.
        This method builds a set of menus and binds handlers to be called
        when the menu item is selected.
        """

        # Make a file menu with Hello and Exit items
        fileMenu = wx.Menu()
        # The "\t..." syntax defines an accelerator key that also triggers
        # the same event
        helloItem = fileMenu.Append(-1, "&CC\tCtrl-C",
                "Help string shown in status bar for this menu item")
        fileMenu.AppendSeparator()
        # When using a stock ID we don't need to specify the menu item's
        # label
        exitItem = fileMenu.Append(wx.ID_EXIT)

        # Now a help menu for the about item
        helpMenu = wx.Menu()
        aboutItem = helpMenu.Append(wx.ID_ABOUT)

        # Make the menu bar and add the two menus to it. The '&' defines
        # that the next letter is the "mnemonic" for the menu item. On the
        # platforms that support it those letters are underlined and can be
        # triggered from the keyboard.
        menuBar = wx.MenuBar()
        menuBar.Append(fileMenu, "&File")
        menuBar.Append(helpMenu, "&Help")

        # Give the menu bar to the frame
        self.SetMenuBar(menuBar)

        # Finally, associate a handler function with the EVT_MENU event for
        # each of the menu items. That means that when that menu item is
        # activated then the associated handler function will be called.
        self.Bind(wx.EVT_MENU, self.OnHello, helloItem)
        self.Bind(wx.EVT_MENU, self.OnExit, exitItem)
        self.Bind(wx.EVT_MENU, self.OnAbout, aboutItem)


    def OnExit(self, event):
        """Close the frame, terminating the application."""
        self.Close(True)


    def OnHello(self, event):
        """Say hello to the user."""
        wx.MessageBox("Smart Machine from CC",      #弹窗的提示内容
                      'Hello')                      #弹窗的提示标题


    def OnAbout(self, event):
        """Display an About Dialog"""
        wx.MessageBox("This is Smart Machine for CC",
                      "Smart Machine",
                       wx.OK | wx.ICON_INFORMATION)


if __name__ == '__main__' :
    # When this module is run (not imported) then create the app, the
    # frame, show it, and start the event loop.
    app = wx.App()
    frm = HelloFrame(None, title='CC')
    frm.Show()
    app.MainLoop()

2/8 更新

这是改善版(添加了多线程读取IO值)

import pyads
import wx
import threading
import time

plc = pyads.Connection('169.254.254.110.1.1', 851)


def plc_connect():
    plc.open()


plc_connect()

# Define notification event for thread completion
EVT_RESULT_ID = wx.NewEventType()


def EVT_RESULT(win, func):
    """Define Result Event."""
    win.Connect(-1, -1, EVT_RESULT_ID, func)


class ResultEvent(wx.PyEvent):
    """Simple event to carry arbitrary result data."""

    def __init__(self, data):
        """Init Result Event."""
        wx.PyEvent.__init__(self)
        self.SetEventType(EVT_RESULT_ID)
        # self.data = data


class HelloFrame(wx.Frame):
    plc.write_by_name('MAIN.A', False, pyads.PLCTYPE_BOOL)
    ClickNum = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)  # 定义变量
    ClickNum1 = 0  # 定义变量
    ClickNum2 = 0  # 定义变量

    """
    A Frame that says Hello World
    """

    def __init__(self, *args, **kw):
        # ensure the parent's __init__ is called
        super(HelloFrame, self).__init__(*args, **kw)

        self.icon1 = wx.Icon(name="wx.jpg", type=wx.BITMAP_TYPE_ANY)
        self.SetIcon(self.icon1)

        # create a panel in the frame
        pnl = wx.Panel(self)

        ReadIoState(self)

        # create a Button
        self.b = wx.Button(pnl, -1, "测试启动", pos=(0, 0))
        self.Bind(wx.EVT_BUTTON, self.OnClick, self.b)
        if self.ClickNum == 1:
            self.b.SetLabel("测试关闭")  # 修改按键的标签
        else:
            self.b.SetLabel("测试启动")

        self.c = wx.Button(pnl, -1, "启动_ON", pos=(0, 30))
        self.c.Bind(wx.EVT_LEFT_DOWN, self.OnClick1)
        self.c.Bind(wx.EVT_LEFT_UP, self.OnClick3)

        self.d = wx.Button(pnl, -1, "停止_ON", pos=(0, 60))
        self.d.Bind(wx.EVT_LEFT_DOWN, self.OnClick2)
        self.d.Bind(wx.EVT_LEFT_UP, self.OnClick4)

        self.e = wx.Button(pnl, -1, "", pos=(0, 90))
        self.e.Bind(wx.EVT_LEFT_UP, self.OnClick5)

        # create a menu bar
        self.makeMenuBar()
        # and a status bar
        self.CreateStatusBar()
        self.SetStatusText("Welcome to CC!")

        EVT_RESULT(self, self.changelable)

    # noinspection PyUnusedLocal
    def changelable(self, msg):
        if start5:
            self.e.SetLabel("工位有料")  # 设置按钮标签
        else:
            self.e.SetLabel("工位无料")  # 设置按钮标签

    # noinspection PyUnusedLocal
    def OnClick(self, event):  # 回调函数事件
        self.ClickNum += 1

        try:
            if self.ClickNum % 2 == 1:  # 根据按下次数判断
                self.b.SetLabel("测试关闭")  # 修改按键的标签
                plc.write_by_name('MAIN.A', True, pyads.PLCTYPE_BOOL)
                start = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
                print(start)
                print(self.b.GetLabel())  # 打印信息(返回按键的标签信息)
                # print(self.ClickNum)
            # elif self.ClickNum % 2 == 3:
            else:
                # time.sleep(0.1)
                self.b.SetLabel("测试启动")
                plc.write_by_name('MAIN.A', False, pyads.PLCTYPE_BOOL)
                start = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
                print(start)
                self.ClickNum = 0
                print(self.b.GetLabel())
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

    def OnClick1(self, event):
        self.c.SetLabel("启动_OFF")  # 修改按键的标签

        try:
            plc.write_by_name('MAIN.A', True, pyads.PLCTYPE_BOOL)
            start1 = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
            print(start1)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.c.GetLabel())  # 打印信息(返回按键的标签信息)
        event.Skip()

    def OnClick3(self, event):
        self.c.SetLabel("启动_ON")  # 修改按键的标签

        try:
            plc.write_by_name('MAIN.A', False, pyads.PLCTYPE_BOOL)
            start1 = plc.read_by_name('MAIN.A', pyads.PLCTYPE_BOOL)
            print(start1)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')
            event.Skip()

        print(self.c.GetLabel())  # 打印信息(返回按键的标签信息)
        event.Skip()

    def OnClick2(self, event):  # 回调函数事件
        self.d.SetLabel("停止_OFF")  # 设置

        try:
            plc.write_by_name('information.rest_all', True, pyads.PLCTYPE_BOOL)
            start2 = plc.read_by_name('information.rest_all', pyads.PLCTYPE_BOOL)
            print(start2)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')
            event.Skip()

        print(self.d.GetLabel())  # 打印信息(返回按键的标签信息)

    def OnClick4(self, event):  # 回调函数事件
        self.d.SetLabel("停止_ON")  # 设置

        try:
            plc.write_by_name('information.rest_all', False, pyads.PLCTYPE_BOOL)
            start2 = plc.read_by_name('information.rest_all', pyads.PLCTYPE_BOOL)
            print(start2)
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')
            event.Skip()

        print(self.d.GetLabel())  # 打印信息(返回按键的标签信息)

    # noinspection PyUnusedLocal
    def OnClick5(self, event):  # 回调函数事件
        pass

        # try:
        #     # plc.write_by_name('information.rest_all', False, pyads.PLCTYPE_BOOL)
        #     start2 = plc.read_by_name('information.rest_all', pyads.PLCTYPE_BOOL)
        #     # print(start2)
        # except pyads.pyads_ex.ADSError:
        #     print('PLC未连接')
        #     event.Skip()

        print(self.d.GetLabel())  # 打印信息(返回按键的标签信息)

    def makeMenuBar(self):
        """
        A menu bar is composed of menus, which are composed of menu items.
        This method builds a set of menus and binds handlers to be called
        when the menu item is selected.
        """

        # Make a file menu with Hello and Exit items
        fileMenu = wx.Menu()
        # The "\t..." syntax defines an accelerator key that also triggers
        # the same event
        helloItem = fileMenu.Append(-1, "&CC\tCtrl-C",
                                    "Help string shown in status bar for this menu item")
        fileMenu.AppendSeparator()
        # When using a stock ID we don't need to specify the menu item's
        # label
        exitItem = fileMenu.Append(wx.ID_EXIT)

        # Now a help menu for the about item
        helpMenu = wx.Menu()
        aboutItem = helpMenu.Append(wx.ID_ABOUT)

        # Make the menu bar and add the two menus to it. The '&' defines
        # that the next letter is the "mnemonic" for the menu item. On the
        # platforms that support it those letters are underlined and can be
        # triggered from the keyboard.
        MenuBar = wx.MenuBar()
        MenuBar.Append(fileMenu, "&File")
        MenuBar.Append(helpMenu, "&Help")

        # Give the menu bar to the frame
        self.SetMenuBar(MenuBar)

        # Finally, associate a handler function with the EVT_MENU event for
        # each of the menu items. That means that when that menu item is
        # activated then the associated handler function will be called.
        self.Bind(wx.EVT_MENU, self.OnHello, helloItem)
        self.Bind(wx.EVT_MENU, self.OnExit, exitItem)
        self.Bind(wx.EVT_MENU, self.OnAbout, aboutItem)

    def OnExit(self):
        """Close the frame, terminating the application."""
        self.Close(True)

    @staticmethod
    def OnHello():
        """Say hello to the user."""
        wx.MessageBox("Smart Machine from CC",  # 弹窗的提示内容
                      'Hello')  # 弹窗的提示标题

    @staticmethod
    def OnAbout():
        """Display an About Dialog"""
        wx.MessageBox("This is Smart Machine for CC",
                      "Smart Machine",
                      wx.OK | wx.ICON_INFORMATION)


class ReadIoState(threading.Thread):
    # def __init__(self, threadID, name, counter):

    def __init__(self, wxObject):
        threading.Thread.__init__(self)
        self.wxObject = wxObject
        self.start()  # start the thread

    def run(self):
        while 1:
            # noinspection PyGlobalUndefined
            global start5
            start5 = plc.read_by_name('MAIN.B', pyads.PLCTYPE_BOOL)
            # if start5 != start5:
            #     print(start5)
            # wx.CallAfter()
            time.sleep(0.2)
            wx.PostEvent(self.wxObject, ResultEvent("ReadIoState"))


if __name__ == '__main__':
    # When this module is run (not imported) then create the app, the
    # frame, show it, and start the event loop.
    app = wx.App()
    frm = HelloFrame(None, title='CC')
    frm.Show()
    app.MainLoop()

2/21更新

(重新用wxFormBuilder设计UI,及实现前后端分离)

python连接AB的PLC读取数据_python连接AB的PLC读取数据_08


更新后的源码:

UI部分:

# -*- coding: utf-8 -*- 

###########################################################################
## Python code generated with wxFormBuilder (version Jun 17 2015)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################

import wx
import wx.xrc

###########################################################################
## Class MyFrame1
###########################################################################

class MyFrame1 ( wx.Frame ):
	
	def __init__( self, parent ):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"CC_ADS", pos = wx.DefaultPosition, size = wx.Size( 1980,820 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
		
		self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
		self.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) )
		self.SetBackgroundColour( wx.Colour( 255, 255, 255 ) )
		
		gSizer1 = wx.GridSizer( 13, 16, 0, 0 )
		
		gSizer2 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.StartButton = wx.Button( self, wx.ID_ANY, u"启动", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer2.Add( self.StartButton, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		self.ResetButton = wx.Button( self, wx.ID_ANY, u"复位", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer2.Add( self.ResetButton, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer2, 1, wx.EXPAND, 5 )
		
		gSizer3 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer3, 1, wx.EXPAND, 5 )
		
		gSizer4 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"入口处急停:", wx.Point( 1,-1 ), wx.DefaultSize, 0 )
		self.m_staticText1.Wrap( -1 )
		self.m_staticText1.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
		self.m_staticText1.SetBackgroundColour( wx.Colour( 255, 255, 255 ) )
		
		gSizer4.Add( self.m_staticText1, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, u"入口处急停1:", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText2.Wrap( -1 )
		self.m_staticText2.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
		
		gSizer4.Add( self.m_staticText2, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer4, 1, wx.EXPAND, 5 )
		
		gSizer5 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.EmergencyButton = wx.Button( self, wx.ID_ANY, u"急停中", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer5.Add( self.EmergencyButton, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		self.EmergencyButton1 = wx.Button( self, wx.ID_ANY, u"急停中", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer5.Add( self.EmergencyButton1, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer5, 1, wx.EXPAND, 5 )
		
		gSizer6 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.m_staticText3 = wx.StaticText( self, wx.ID_ANY, u"入口处急停2:", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText3.Wrap( -1 )
		self.m_staticText3.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
		
		gSizer6.Add( self.m_staticText3, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		self.m_staticText4 = wx.StaticText( self, wx.ID_ANY, u"左出口处急停:", wx.Point( 1,-1 ), wx.DefaultSize, 0 )
		self.m_staticText4.Wrap( -1 )
		self.m_staticText4.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
		self.m_staticText4.SetBackgroundColour( wx.Colour( 255, 255, 255 ) )
		
		gSizer6.Add( self.m_staticText4, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer6, 1, wx.EXPAND, 5 )
		
		gSizer7 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.EmergencyButton2 = wx.Button( self, wx.ID_ANY, u"急停中", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer7.Add( self.EmergencyButton2, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		self.EmergencyButton3 = wx.Button( self, wx.ID_ANY, u"急停中", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer7.Add( self.EmergencyButton3, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer7, 1, wx.EXPAND, 5 )
		
		gSizer8 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.m_staticText5 = wx.StaticText( self, wx.ID_ANY, u"右出口处急停:", wx.DefaultPosition, wx.DefaultSize, 0 )
		self.m_staticText5.Wrap( -1 )
		self.m_staticText5.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
		
		gSizer8.Add( self.m_staticText5, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer8, 1, wx.EXPAND, 5 )
		
		gSizer9 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.EmergencyButton4 = wx.Button( self, wx.ID_ANY, u"急停中", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer9.Add( self.EmergencyButton4, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer9, 1, wx.EXPAND, 5 )
		
		gSizer10 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer10, 1, wx.EXPAND, 5 )
		
		gSizer11 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer11, 1, wx.EXPAND, 5 )
		
		gSizer12 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer12, 1, wx.EXPAND, 5 )
		
		gSizer13 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer13, 1, wx.EXPAND, 5 )
		
		gSizer14 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer14, 1, wx.EXPAND, 5 )
		
		gSizer15 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer15, 1, wx.EXPAND, 5 )
		
		gSizer16 = wx.GridSizer( 0, 1, 0, 0 )
		
		
		gSizer1.Add( gSizer16, 1, wx.EXPAND, 5 )
		
		gSizer17 = wx.GridSizer( 0, 1, 0, 0 )
		
		m_choice1Choices = [ u"第一页", u"第二页", u"第三页" ]
		self.m_choice1 = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice1Choices, 0 )
		self.m_choice1.SetSelection( 0 )
		gSizer17.Add( self.m_choice1, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer17, 1, wx.EXPAND, 5 )
		
		gSizer18 = wx.GridSizer( 0, 1, 0, 0 )
		
		self.m_button157 = wx.Button( self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer18.Add( self.m_button157, 0, wx.ALL, 5 )
		
		self.m_button158 = wx.Button( self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0 )
		gSizer18.Add( self.m_button158, 0, wx.ALL, 5 )
		
		
		gSizer1.Add( gSizer18, 1, wx.EXPAND, 5 )
		
		gSizer19 = wx.GridSizer( 0, 2, 0, 0 )
		
		
		gSizer1.Add( gSizer19, 1, wx.EXPAND, 5 )
		
		
		self.SetSizer( gSizer1 )
		self.Layout()
		
		self.Centre( wx.BOTH )
		
		# Connect Events
		self.StartButton.Bind( wx.EVT_LEFT_UP, self.StartEvent )
		self.ResetButton.Bind( wx.EVT_LEFT_UP, self.ResetEvent )
	
	def __del__( self ):
		pass
	
	
	# Virtual event handlers, overide them in your derived class
	def StartEvent( self, event ):
		event.Skip()
	
	def ResetEvent( self, event ):
		event.Skip()

程序控制部分:

"""Subclass of MyFrame1, which is generated by wxFormBuilder."""

import wx
import UI
import threading
import time
import pyads

plc = pyads.Connection('5.71.183.236.1.1', 851)
plc.open()

# Define notification event for thread completion
EVT_RESULT_ID = wx.NewEventType()


def EVT_RESULT(win, func):
    """Define Result Event."""
    win.Connect(-1, -1, EVT_RESULT_ID, func)


class ResultEvent(wx.PyEvent):
    """Simple event to carry arbitrary result data."""

    # noinspection PyUnusedLocal
    def __init__(self, data):
        """Init Result Event."""
        wx.PyEvent.__init__(self)
        self.SetEventType(EVT_RESULT_ID)


# Implementing MyFrame1
class ADS(UI.MyFrame1):
    def __init__(self, parent):
        UI.MyFrame1.__init__(self, parent)

        # self.icon1 = wx.Icon(name="wx.jpg", type=wx.BITMAP_TYPE_ANY)
        # self.SetIcon(self.icon1)

        ReadIoState(self)

        EVT_RESULT(self, self.changelable)

    # noinspection PyUnusedLocal
    def changelable(self, msg):
        if Enter_Emergency:
            self.EmergencyButton.SetLabel("运行中")  # 设置按钮标签
        else:
            self.EmergencyButton.SetLabel("急停中")  # 设置按钮标签

        if Enter_Emergency_1:
            self.EmergencyButton1.SetLabel("运行中")  # 设置按钮标签
        else:
            self.EmergencyButton1.SetLabel("急停中")  # 设置按钮标签

        if Enter_Emergency_2:
            self.EmergencyButton2.SetLabel("运行中")  # 设置按钮标签
        else:
            self.EmergencyButton2.SetLabel("急停中")  # 设置按钮标签

        if Enter_Emergency_3:
            self.EmergencyButton3.SetLabel("运行中")  # 设置按钮标签
        else:
            self.EmergencyButton3.SetLabel("急停中")  # 设置按钮标签

        if Enter_Emergency_4:
            self.EmergencyButton4.SetLabel("运行中")  # 设置按钮标签
        else:
            self.EmergencyButton4.SetLabel("急停中")  # 设置按钮标签

    # Handlers for MyFrame1 events.
    def StartEvent(self, event):
        # self.StartButton.SetLabel("启动_OFF")  # 修改按键的标签

        try:
            plc.write_by_name('MAIN.TEST_1', True, pyads.PLCTYPE_BOOL)
            Start1 = plc.read_by_name('MAIN.TEST_1', pyads.PLCTYPE_BOOL)
            print(Start1)
            self.StartButton.SetLabel("启动")  # 修改按键的标签
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.StartButton.GetLabel())  # 打印信息(返回按键的标签信息)
        event.Skip()

    def ResetEvent(self, event):
        # self.ResetButton.SetLabel("复位_OFF")

        try:
            plc.write_by_name('information.rest_all', True, pyads.PLCTYPE_BOOL)
            Start2 = plc.read_by_name('information.rest_all', pyads.PLCTYPE_BOOL)
            print(Start2)
            self.ResetButton.SetLabel("复位")
        except pyads.pyads_ex.ADSError:
            print('PLC未连接')

        print(self.ResetButton.GetLabel())  # 打印信息(返回按键的标签信息)
        event.Skip()


class ReadIoState(threading.Thread):
    # def __init__(self, threadID, name, counter):

    def __init__(self, wxObject):
        threading.Thread.__init__(self)
        self.wxObject = wxObject
        self.start()  # start the thread
        self.stop_event = threading.Event()

    def stop(self):
        self.stop_event.clear()

    def run(self):
        while 1:
            # noinspection PyGlobalUndefined
            global Enter_Emergency
            # noinspection PyGlobalUndefined
            global Enter_Emergency_1
            # noinspection PyGlobalUndefined
            global Enter_Emergency_2
            # noinspection PyGlobalUndefined
            global Enter_Emergency_3
            # noinspection PyGlobalUndefined
            global Enter_Emergency_4

            try:
                Enter_Emergency = plc.read_by_name('INOUTPUT.stinput.Enter_Emergency', pyads.PLCTYPE_BOOL)
                Enter_Emergency_1 = plc.read_by_name('INOUTPUT.stinput.Enter_emergency_1', pyads.PLCTYPE_BOOL)
                Enter_Emergency_2 = plc.read_by_name('INOUTPUT.stinput.Enter_emergency_2', pyads.PLCTYPE_BOOL)
                Enter_Emergency_3 = plc.read_by_name('INOUTPUT.stinput.left_out_emergency', pyads.PLCTYPE_BOOL)
                Enter_Emergency_4 = plc.read_by_name('INOUTPUT.stinput.right_out_emergency', pyads.PLCTYPE_BOOL)
            except pyads.pyads_ex.ADSError:
                print('PLC未连接')

            time.sleep(0.01)
            wx.PostEvent(self.wxObject, ResultEvent("ReadIoState"))


if __name__ == '__main__':
    # When this module is run (not imported) then create the app, the
    # frame, show it, and start the event loop.
    app = wx.App()
    frm = ADS(None)
    frm.Show()
    app.MainLoop()