Commits

gfcheng committed 5f54351

接收数据功能实现

Comments (0)

Files changed (2)

 #import sys
 import threading
 import time
+import binascii
 class WinMain(wx.Frame):
 
     def __init__(self):
             wx.DefaultPosition, wx.Size(500, 400), wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
 
         self.threads = []
-        self.ports = ['COM1','COM2','COM3']
-        self.port_dict = {}
-        self.port_number = ""
+        self.serial_ports = []
+        self.cur_port_number = ""
+        self.cur_port_com = ""
         self.find_no_port = True
         self.is_linking_to_port = False
+        # 循环扫描可用COM端
+        #for i in range(256):
+            #try:
+                #s = serial.Serial(i)
+                #self.serial_ports.append([i, s.portstr])
+                #s.close()
+                #break
+            #except serial.SerialException:
+                #pass
+        self.serial = serial.Serial()
 
-        # 得出可用COM端
-        self.serial_ports = self.Scan()
-        if not self.serial_ports:
-            pass
-        else:
-            self.find_no_port = False
-            self.port_dict = dict(self.serial_ports)
-            self.ports = ["%s" %i[0] for i  in self.serial_ports]
+        self.serial_ports = ('COM1','COM2','COM3','COM4','COM5')
+        self.serial_port_dict = self.List_To_Dict(self.serial_ports)
+        self.serial_baudrate_dict =self.List_To_Dict(self.serial.BAUDRATES)
+        self.serial_bytesize_dict =self.List_To_Dict(self.serial.BYTESIZES)
+        self.serial_stopbits_dict= self.List_To_Dict(self.serial.STOPBITS)
+        self.serial_parity_dict = self.List_To_Dict(self.serial.PARITIES)
 
-        #系统图标
         self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
 
         sizer_top = wx.BoxSizer(wx.VERTICAL)
             wx.DefaultPosition, wx.DefaultSize, 0)
         sizer_option_2.Add(self.option_2_st1, 0, wx.ALL, 5)
 
-        self.option_port = wx.ComboBox(self.panel, wx.ID_ANY,
-            'COM1', wx.DefaultPosition, wx.DefaultSize, self.ports,
-            wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER | wx.CB_READONLY)
+        self.option_port = wx.Choice(self.panel, wx.ID_ANY,
+             wx.DefaultPosition, wx.DefaultSize, self.serial_port_dict.values())
         sizer_option_2.Add(self.option_port, 0, wx.ALL, 5)
 
         # 设置波特率
             wx.DefaultPosition, wx.DefaultSize, 0)
         sizer_option_2.Add(self.option_2_st2, 0, wx.ALL, 5)
 
-        self.option_baudrate = wx.ComboBox(self.panel, wx.ID_ANY,
-            '9600', wx.DefaultPosition, wx.DefaultSize,
-            ['110','300','600','1200','2400','4800','9600',
-            '14400','19200','38400','56000','57600','115200','128000','256000'],
-            wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER | wx.CB_READONLY)
+        self.option_baudrate = wx.Choice(self.panel, wx.ID_ANY,
+            wx.DefaultPosition, wx.DefaultSize, self.serial_baudrate_dict.values())
         sizer_option_2.Add(self.option_baudrate, 0, wx.ALL, 5)
 
         self.open_port_button = wx.Button(self.panel, wx.ID_ANY,
             u'打开串口', wx.DefaultPosition, wx.DefaultSize, 0)
         sizer_option_2.Add(self.open_port_button, 1, wx.ALL, 5)
 
+        self.close_port_button = wx.Button(self.panel, wx.ID_ANY,
+            u'关闭串口', wx.DefaultPosition, wx.DefaultSize, 0)
+        sizer_option_2.Add(self.close_port_button, 1, wx.ALL, 5)
+
         #预留图标
+        #self.static_png = wx.Image(r'res/unlink.png', wx.BITMAP_TYPE_PNG)
+        #self.static_bitmap = wx.StaticBitmap(self.panel, wx.ID_ANY,
+                #wx.BitmapFromImage(self.static_png),(16,16))
+
+        #sizer_option_2.Add(self.static_bitmap, 0, wx.ALL, 5)
+        #
         self.send_as_hex = wx.CheckBox(self.panel, wx.ID_ANY,
             u'HEX发送',
             wx.DefaultPosition, wx.DefaultSize, 0)
             wx.DefaultPosition, wx.DefaultSize, 0)
         sizer_option_3.Add(self.option_3_st1, 0, wx.ALL, 5)
 
-        self.option_bytesize = wx.ComboBox(self.panel, wx.ID_ANY,
-            '8', wx.DefaultPosition, wx.DefaultSize, ['5','6','7','8'],
-            wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER | wx.CB_READONLY)
+        self.option_bytesize = wx.Choice(self.panel, wx.ID_ANY,
+             wx.DefaultPosition, wx.DefaultSize, self.serial_bytesize_dict.values())
         sizer_option_3.Add(self.option_bytesize, 0, wx.ALL, 5)
 
         # 设置停止位
             wx.DefaultPosition, wx.DefaultSize, 0)
         sizer_option_3.Add(self.option_3_st2, 0, wx.ALL, 5)
 
-        self.option_stopbits = wx.ComboBox(self.panel, wx.ID_ANY,
-            '1', wx.DefaultPosition, wx.DefaultSize, ['1','1.5','2'],
-            wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER | wx.CB_READONLY)
+        self.option_stopbits = wx.Choice(self.panel, wx.ID_ANY,
+             wx.DefaultPosition, wx.DefaultSize, self.serial_stopbits_dict.values())
         sizer_option_3.Add(self.option_stopbits, 0, wx.ALL, 5)
 
         # 设置校验位
             wx.DefaultPosition, wx.DefaultSize, 0)
         sizer_option_3.Add(self.option_3_st3, 0, wx.ALL, 5)
 
-        self.option_parity = wx.ComboBox(self.panel, wx.ID_ANY,
-            'None', wx.DefaultPosition, wx.DefaultSize, ['None','Odd','Even','Mark','Space'],
-            wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER | wx.CB_READONLY)
+        self.option_parity = wx.Choice(self.panel, wx.ID_ANY,
+            wx.DefaultPosition, wx.DefaultSize,  self.serial_parity_dict.values())
         sizer_option_3.Add(self.option_parity, 0, wx.ALL, 5)
 
         self.help_button = wx.Button(self.panel, wx.ID_ANY,
         self.CreateStatusBar(3)
         self.SetStatusWidths([-3,-4,-3])
         self.SetStatusText(u"    a python script",0)
-        if self.find_no_port:
-            self.SetStatusText(u"未发现串口",2)
 
         # 菜单条
 
 
         # 绑定事件
         self.Bind(wx.EVT_BUTTON, self.OnClear, self.clear_button)
-        self.Bind(wx.EVT_BUTTON, self.OnSend, self.send_button)
-        self.Bind(wx.EVT_BUTTON, self.OnLink_To_Port, self.open_port_button)
+        #self.Bind(wx.EVT_BUTTON, self.OnSend, self.send_button)
+        self.Bind(wx.EVT_BUTTON, self.OnOpen_Port, self.open_port_button)
+        self.Bind(wx.EVT_BUTTON, self.OnClose_Port, self.close_port_button)
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 
-    # 扫描可用COM端
-    def Scan(self):
-        available = []
-        for i in range(256):
-            try:
-                s = serial.Serial(i)
-                available.append((s.portstr,i))
-                s.close()
-                #break
-            except serial.SerialException:
-                pass
-        return available
-
-
-    def OnSend(self, event):
-        print "Onsend"
-        #self.task = WorkerThread(8,self)
-        # self.task.start()
-        #pass
-
-    def OnLink_To_Port(self, event):
-        if not self.find_no_port:
-            print self.option_port.GetValue()
-            self.port_number = self.port_dict[self.option_port.GetValue()]
+        self.option_port.SetSelection(1)
+        self.option_baudrate.SetSelection(12)
+        self.option_bytesize.SetSelection(3)
+        self.option_stopbits.SetSelection(0)
+        self.option_parity.SetSelection(0)
+
+
+        self.option_newline = 2
+        #print self.serial_port_dict
+    def List_To_Dict(self, m_list):
+            n_list = []
+            for i in range(len(m_list)):
+                n_list.append([i, str(m_list[i])])
+            return dict(n_list)
+
+        #wx.MessageBox(u'当前串口号被占用,或其它错误','ERROR', wx.OK | wx.ICON_EXCLAMATION)
+
+    def OnOpen_Port(self, event):
+        try:
+            self.serial.port =  self.option_port.GetSelection()
+            self.serial.baudrate = int(self.serial_baudrate_dict[self.option_baudrate.GetSelection()])
+            self.serial.bytesize = int(self.serial_bytesize_dict[self.option_bytesize.GetSelection()])
+            self.serial.stopbits = int(self.serial_stopbits_dict[self.option_stopbits.GetSelection()])
+            self.serial.parity = self.serial_parity_dict[self.option_parity.GetSelection()]
+        except:
+            self.OnClose_Port(self) # 不加参数会出错
+        # 这里有1个BUG,判断isOpen()每次都为False
+        if not self.is_linking_to_port:
+            #print "open port"
             try:
-                self.ser = serial.Serial(self.port_number)
+                self.serial.open()
             except:
-                # 关闭程序自身打开的串口
-                if self.is_linking_to_port:                
-                    self.ser.close()
-                    self.is_linking_to_port = False
-                    print u"关闭了串口"
-                    self.open_port_button.SetLabel(u"打开串口")
-                # 无法关闭正在被其它程序占用的串口
-                else:
-                    print u"当前串口号被占用,或其它错误!"
-                    wx.MessageBox(u'当前串口号被占用,或其它错误','ERROR',
-                                wx.OK | wx.ICON_EXCLAMATION)
+                self.SetStatusText(u"打开串口失败",2)
             else:
-                print u"打开了串口"
+                print self.serial
                 self.is_linking_to_port = True
-                self.open_port_button.SetLabel(u"关闭串口")
+                self.SetStatusText(u"已连接%s  [%s-%s-%s-%s]" % (self.serial_port_dict[self.option_port.GetSelection()],
+                    self.serial.baudrate, self.serial.bytesize,self.serial.stopbits, self.serial.parity),1)
+                self.SetStatusText(u"",2)
+                self.task = Recv_Thread(self,self.serial)
+                self.task.start()
+
+    def OnClose_Port(self, event):
+        #print self.serial
+        if self.is_linking_to_port:
+            self.task.stop()
+            self.serial.close()
+            self.is_linking_to_port = False
+            self.SetStatusText(u"未连接串口",1)
 
     def OnClear(self, event):
         self.recv_text.Clear()
         self.send_text.Clear()
 
     def OnCloseWindow(self, event):
+        try:
+            self.serial.close()
+        except:
+            pass
+        self.OnClose_Port(self)
         self.Destroy()
 
-    def insert(self,msg):
-        self.recv_text.AppendText(msg)
-class WorkerThread(threading.Thread):
-    def __init__(self,n,window):
+    def Update_Recv_Text(self, text):
+        #if self.display_as_hex.IsChecked:
+            #self.recv_text.AppendText(binascii.b2a_hex(text))
+        #else:
+            #text = ''.join([(c >= ' ') and c or '<%d>' % ord(c)  for c in text])
+        text = text.replace('\r\n', '\n')
+        text = text.replace('\r', '\n')
+        if self.display_as_hex.IsChecked():
+            text = binascii.b2a_hex(text)
+            print text
+            text = text.replace('0a', '\n')
+            print 
+        self.recv_text.AppendText(text)
+
+        
+
+class Recv_Thread(threading.Thread):
+    def __init__(self, window, ser):
         threading.Thread.__init__(self)
-        self.max = n
         self.window = window
+        self.serial = ser
+        self.time_to_quit = threading.Event()
+        self.time_to_quit.clear()
+
+    def stop(self):
+        self.time_to_quit.set()
+
     def run(self):
-        while self.max:
-            time.sleep(1)
-            self.max -= 1
-            print self.max
-            wx.CallAfter(self.window.insert, str(self.max))
+        #print "run"
+        while self.serial.isOpen():
+            #print "ok"
+            if self.time_to_quit.isSet():
+                break
+            text = self.serial.read(1)  #读一个字符
+            if text:
+                n = self.serial.inWaiting() #检查是否还有未接收的字符
+                if n:
+                    text = text + self.serial.read(n)
+                wx.CallAfter(self.window.Update_Recv_Text, text)
+            #time.sleep(0.5)
+        print "stop"
 
 if __name__ == '__main__':
     app = wx.App(False)

src/test/stop_child_thread.py

+# coding:utf-8
+# 测试主线程和子线程的通信
+# 开中断关闭子线程
+import sys
+import threading
+import wx
+import time
+
+class WinMain(wx.Frame):
+
+    def __init__(self):
+        wx.Frame.__init__(self, None, wx.ID_ANY, u"win_main.py",
+            wx.DefaultPosition, wx.Size(300, 300), wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
+
+        self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
+        sizer_top = wx.BoxSizer(wx.VERTICAL)
+        self.panel = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
+        sizer_main = wx.BoxSizer(wx.HORIZONTAL)
+
+        sizer_button = wx.BoxSizer(wx.VERTICAL)
+        self.open_port_button = wx.Button(self.panel, wx.ID_ANY,
+            u'打开串口', wx.DefaultPosition, wx.DefaultSize, 0)
+        sizer_button.Add(self.open_port_button, 1, wx.ALL, 5)
+
+        self.close_port_button = wx.Button(self.panel, wx.ID_ANY,
+            u'关闭串口', wx.DefaultPosition, wx.DefaultSize, 0)
+        sizer_button.Add(self.close_port_button, 1, wx.ALL, 5)
+        sizer_main.Add(sizer_button, 0, wx.EXPAND |wx.ALL, 0)
+
+        self.recv_text = wx.TextCtrl(self.panel, wx.ID_ANY,
+            u"",wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE)
+        sizer_main.Add(self.recv_text, 1, wx.ALL | wx.EXPAND, 5)
+        # SetSizer
+        self.panel.SetSizer(sizer_main)
+        self.panel.Layout()
+        sizer_main.Fit(self.panel)
+        sizer_top.Add(self.panel, 1, wx.EXPAND |wx.ALL, 0)
+
+        self.SetSizer(sizer_top)
+        self.Layout()
+
+        self.Centre(wx.BOTH)
+
+        # 绑定事件
+        self.Bind(wx.EVT_CLOSE, self.OnExit)
+        self.Bind(wx.EVT_BUTTON, self.OnOpen, self.open_port_button)
+        self.Bind(wx.EVT_BUTTON, self.OnClose, self.close_port_button)
+
+    def OnOpen(self, event):
+        self.task = Work_Thread(self, 10)
+        self.task.start()
+
+    def OnClose(self, event):
+        self.task.stop()
+        self.task.join()
+    def OnExit(self, event):
+        self.Destroy()
+        sys.exit()
+
+    def Update_Recv_Text(self, text):
+        self.recv_text.AppendText(text)
+
+class Work_Thread(threading.Thread):
+    def __init__(self, window, num):
+        threading.Thread.__init__(self)
+        self.window = window
+        self.num = num
+        self.time_to_quit = threading.Event()
+        self.time_to_quit.clear()
+    def stop(self):
+        self.time_to_quit.set()
+    def run(self):
+        print "run"
+        print self.time_to_quit.isSet()
+        while self.num:
+            print self.num
+            wx.CallAfter(self.window.Update_Recv_Text, str(self.num)+"\n")
+            self.num -= 1
+            if self.time_to_quit.isSet():
+                print "interrupt"
+                break
+            time.sleep(1)
+        print "run over"
+
+if __name__ == '__main__':
+    app = wx.App(False)
+
+    window_main = WinMain()
+    window_main.Show()
+
+    app.MainLoop()