python的for循环🔁次数多(不能减少),导致wx窗体未响应改怎么改进,才能让他一直运行 不出现未响应的情况
将所有耗时任务交给线程去做,另起一个方法,将for循环写在函数内,将变量用 global name的方式导入进去
如果for 循环完成后需要改变界面,直接在内调用对应对象设置值就好了
这是一个机器人控制界面,涉及到死循环和页面卡死的问题,用线程就可以完美解决了,python 版本是2.7的 ,你要运行可能要修改一下
# -*- coding:utf-8 -*-
import re
import time
import wx
import wx.lib.buttons as lib_button
import select
import sys
import termios
import tty
import threading
import rospy
from geometry_msgs.msg import Twist
runmark = False
speed = 0.2
turn = 0.2
x = 0
th = 0
status = 0
x_acc = 0.1
th_acc = 0.05
target_speed = 0
target_turn = 0
control_speed = 0
control_turn = 0
pub = None
moveBindings = {
'q': (1, 1),
'w': (1, 0),
'8': (1, 0),
'e': (1, -1),
'a': (0, 1),
'4': (0, 1),
'd': (0, -1),
'6': (0, -1),
'z': (-1, 1),
's': (-1, 0),
'2': (-1, 0),
'c': (-1, -1)
}
speedBindings = {
'u': (0.1, 0),
'7': (0.1, 0),
'j': (-0.1, 0),
'1': (-0.1, 0),
'i': (0, 0.05),
'9': (0, 0.05),
'k': (0, -0.05),
'3': (0, -0.05)
}
def vels(speed, turn):
return "currently:\tspeed %s\tturn %s " % (speed, turn)
class Frame(wx.Frame):
inputkeytxt = "点此处按键操作"
def __init__(self):
wx.Frame.__init__(self, None, title='', size=(1496, 809), name='frame', style=541072960)
self.root = wx.Panel(self)
self.Centre()
self.travelspeedplus = wx.Button(self.root, size=(140, 40), pos=(20, 19), label='行进速度加', name='button')
self.travelspeedplus.Bind(wx.EVT_BUTTON, self.travelspeedplus_click)
self.forward = wx.Button(self.root, size=(140, 41), pos=(220, 20), label='前进', name='button')
self.forward.Bind(wx.EVT_LEFT_DOWN, self.forward_onclick)
self.forward.Bind(wx.EVT_LEFT_UP, self.forward_upclick)
self.steeringspeedplus = wx.Button(self.root, size=(140, 40), pos=(420, 21), label='转向速度加', name='button')
self.steeringspeedplus.Bind(wx.EVT_BUTTON, self.steeringspeedplus_click)
self.turnleft = wx.Button(self.root, size=(140, 40), pos=(20, 120), label='左转', name='button')
self.turnleft.Bind(wx.EVT_LEFT_DOWN, self.turnleft_onclick)
self.turnleft.Bind(wx.EVT_LEFT_UP, self.turnleft_upclick)
self.stop = wx.Button(self.root, size=(140, 40), pos=(220, 120), label='停止', name='button')
self.stop.Bind(wx.EVT_BUTTON, self.stop_click)
self.turnright = wx.Button(self.root, size=(140, 40), pos=(420, 120), label='右转', name='button')
self.turnright.Bind(wx.EVT_LEFT_DOWN, self.turnright_onclick)
self.turnright.Bind(wx.EVT_LEFT_UP, self.turnright_upclick)
self.travelspeedreduction = wx.Button(self.root, size=(140, 40), pos=(20, 220), label='行进速度减', name='button')
self.travelspeedreduction.Bind(wx.EVT_BUTTON, self.travelspeedreduction_click)
self.backoff = wx.Button(self.root, size=(140, 40), pos=(220, 220), label='后退', name='button')
self.backoff.Bind(wx.EVT_LEFT_DOWN, self.backoff_onclick)
self.backoff.Bind(wx.EVT_LEFT_UP, self.backoff_upclick)
self.steeringdeceleration = wx.Button(self.root, size=(140, 40), pos=(420, 219), label='转向速度减', name='button')
self.steeringdeceleration.Bind(wx.EVT_BUTTON, self.steeringdeceleration_click)
self.inputkey = wx.TextCtrl(self.root, size=(481, 54), pos=(35, 669), value=self.inputkeytxt, name='text',
style=256)
self.inputkey.Bind(wx.EVT_TEXT, self.inputkey_onchange)
self.inputkey.Bind(wx.EVT_SET_FOCUS, self.inputkey_hover)
self.staticBitmap = wx.StaticBitmap(self.root, size=(861, 728), pos=(608, 23), name='staticBitmap', style=0)
self.show1 = lib_button.ThemedGenBitmapTextButton(self.root, size=(140, 40), pos=(20, 344), bitmap=None,
label='行进速度', name='genbutton')
self.show1.Disable()
self.show2 = lib_button.ThemedGenBitmapTextButton(self.root, size=(140, 40), pos=(20, 408), bitmap=None,
label='转向速度', name='genbutton')
self.show2.Disable()
self.gouptxt = wx.TextCtrl(self.root, size=(320, 40), pos=(198, 344), name='text', value=str(speed), style=16)
self.gouptxt.Disable()
self.turnuptxt = wx.TextCtrl(self.root, size=(320, 39), pos=(198, 408), name='text', value=str(turn), style=16)
self.turnuptxt.Disable()
image = wx.Image('img.png').Scale(778, 707).ConvertToBitmap()
self.images = wx.StaticBitmap(self.root, bitmap=image, size=(778, 707), pos=(642, 20), name='staticBitmap',
style=33554432)
def travelspeedplus_click(self, event):
# 行进速度加
global speed
speed += 0.1
self.gouptxt.SetValue(str(round(speed, 1)))
def forward_upclick(self, event):
# 停止前进
global runmark
runmark = False
def forward_onclick(self, event):
# 前进
global runmark
global moveBindings
global x
global th
x = moveBindings['8'][0]
th = moveBindings['8'][1]
runmark = True
threading.Thread(target=self.run_click).start()
def steeringspeedplus_click(self, event):
# 转向速度加
global turn
turn += 0.1
self.turnuptxt.SetValue(str(round(turn, 1)))
def turnleft_upclick(self, event):
# 停止左转
global runmark
runmark = False
def turnleft_onclick(self, event):
# 左转
global runmark
global moveBindings
global x
global th
x = moveBindings['4'][0]
th = moveBindings['4'][1]
runmark = True
threading.Thread(target=self.run_click).start()
def stop_click(self, event):
global x, th, control_turn, control_speed
x = 0
th = 0
control_speed = 0
control_turn = 0
self.run_click()
def turnright_upclick(self, event):
global runmark
runmark = False
def turnright_onclick(self, event):
global runmark
global moveBindings
global x
global th
x = moveBindings['6'][0]
th = moveBindings['6'][1]
runmark = True
threading.Thread(target=self.run_click).start()
def travelspeedreduction_click(self, event):
global speed
speed -= 0.1
if speed < 0:
speed = 0
self.gouptxt.SetValue(str(round(speed, 2)))
def backoff_upclick(self, event):
global runmark
runmark = False
def backoff_onclick(self, event):
global runmark
global moveBindings
global x
global th
x = moveBindings['2'][0]
th = moveBindings['2'][1]
runmark = True
threading.Thread(target=self.run_click).start()
#
def steeringdeceleration_click(self, event):
global turn
turn -= 0.05
if turn < 0:
turn = 0
self.turnuptxt.SetValue(str(round(turn, 2)))
# 键盘输入操作
def inputkey_onchange(self, event):
global speed
global turn
global x
global th
global control_speed
global control_turn
global target_speed
global target_turn
global x_acc
global th_acc
global speedBindings
global moveBindings
stringvalue = self.inputkey.GetValue()
try:
key = re.findall('[\da-zA-Z ]', stringvalue)[0]
if key in moveBindings.keys():
x = moveBindings[key][0]
th = moveBindings[key][1]
self.goto_robot(speed, th, th_acc, turn, x, x_acc)
elif key in speedBindings.keys():
speed = speed + speedBindings[key][0]
turn = turn + speedBindings[key][1]
if speed <= 0:
speed = 0
if turn <= 0:
turn = 0
elif key == ' ' or key == '5':
x = 0
th = 0
control_speed = 0
control_turn = 0
if speed < 0:
speed = 0
if turn < 0:
turn = 0
self.gouptxt.SetValue(str(round(speed, 2)))
self.turnuptxt.SetValue(str(round(turn, 2)))
except IndexError:
pass
except Exception as e:
print e, 123
if stringvalue != self.inputkeytxt:
self.inputkey.SetValue(self.inputkeytxt)
# 机器人操作指令
def goto_robot(self, speed, th, th_acc, turn, x, x_acc):
global control_speed, control_turn, target_speed, target_turn
if target_speed > control_speed:
control_speed = min(target_speed, control_speed + x_acc)
elif target_speed < control_speed:
control_speed = max(target_speed, control_speed - x_acc)
else:
control_speed = target_speed
if target_turn > control_turn:
control_turn = min(target_turn, control_turn + th_acc)
elif target_turn < control_turn:
control_turn = max(target_turn, control_turn - th_acc)
else:
control_turn = target_turn
target_speed = speed * x
target_turn = turn * th
twist = Twist()
twist.linear.x = control_speed
twist.linear.y = 0
twist.linear.z = 0
twist.angular.x = 0
twist.angular.y = 0
twist.angular.z = control_turn
pub.publish(twist)
def inputkey_hover(self, event):
self.inputkeytxt = self.inputkey.GetValue()
def run_click(self):
global runmark
global speed
global th
global th_acc
global turn
global x
global x_acc
global pub
while runmark:
try:
time.sleep(0.1)
self.goto_robot(speed, th, th_acc, turn, x, x_acc)
except Exception as e:
print e
twist = Twist()
twist.linear.x = 0
twist.linear.y = 0
twist.linear.z = 0
twist.angular.x = 0
twist.angular.y = 0
twist.angular.z = 0
pub.publish(twist)
class myApp(wx.App):
def OnInit(self):
self.frame = Frame()
self.frame.Show(True)
return True
def startinitstyem():
cmd = "roslaunch xbot_navigation run.launch"
import os
info = os.popen(cmd).read()
print info
def startinitstyem1():
cmd = "rviz"
import os
info = os.popen(cmd).read()
print info
if __name__ == '__main__':
import time
threading.Thread(target=startinitstyem).start()
time.sleep(3)
threading.Thread(target=startinitstyem1).start()
rospy.init_node('robot_key_control')
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=5)
app = myApp()
app.MainLoop()