PyQt5 QPushButton问题

fyh82615919 2018-07-15 02:36:55
现在刚刚学习PyQt5,正在实现一个界面控制ros机器人移动的问题。想要实现长按按钮或是对应的快捷键,通过rosbridge发布机器人对应的移动速度消息,松开按键机器人停下,也就是发布0速度的消息。现在QPushButton一直不能实现这样的功能。
尝试过setAutoRepeat,但是按钮长按的时候released和clicked信号不断被触发,而不是只在松开按钮的时候触发,0速度的停止消息会被不断的触发。
尝试过使用QTimer,pressed的时候打开定时器循环触发速度消息,released的时候关闭计时器并断开连接。这样鼠标点按按钮没有问题了,但使用快捷键长按依然出现了循环触发released信号的问题。尝试对其中一个方向按钮重写了keypressedevent来判断按键发送不同的消息,但是按键也没有反应,好像是事件没有聚焦到那个按钮上。现在还是不知道快捷键的问题怎么解决。。。
希望有大神能够指点一二,谢谢!
mainwindow的代码:
class MonitorMainWin(QMainWindow, Ui_MainWindow):
def __init__(self, host):
# setup gui
super(MonitorMainWin, self).__init__()
self.setupUi(self)

# setup socket
self.moveClter = MoveCtl.MoverClter(HOST, PORT_ROS_BRIDGE)

# setup control event
self.control_speed = 0.
self.control_turn = 0.
self.setupMoveBtnEvent()
self.moveCmdTimer = QTimer(self)

def setupMoveBtnEvent(self):
# send messages tp cmd_vel topic if the key is long pressed
self.btn_front_left.pressed.connect(lambda: self.sendMoveCmdLoop(0))
self.btn_front.pressed.connect(lambda: self.sendMoveCmdLoop(1))
self.btn_front_right.pressed.connect(lambda: self.sendMoveCmdLoop(2))
self.btn_left.pressed.connect(lambda: self.sendMoveCmdLoop(3))
self.btn_stop.pressed.connect(lambda: self.sendMoveCmdLoop(4))
self.btn_right.pressed.connect(lambda: self.sendMoveCmdLoop(5))
self.btn_behind_left.pressed.connect(lambda: self.sendMoveCmdLoop(6))
self.btn_behind.pressed.connect(lambda: self.sendMoveCmdLoop(7))
self.btn_behind_right.pressed.connect(lambda: self.sendMoveCmdLoop(8))

self.btn_front_left.released.connect(self.timerResetCmd)
self.btn_front.released.connect(self.timerResetCmd)
self.btn_front_right.released.connect(self.timerResetCmd)
self.btn_left.released.connect(self.timerResetCmd)
self.btn_stop.released.connect(self.timerResetCmd)
self.btn_right.released.connect(self.timerResetCmd)
self.btn_behind_left.released.connect(self.timerResetCmd)
self.btn_behind.released.connect(self.timerResetCmd)
self.btn_behind_right.released.connect(self.timerResetCmd)

self.btn_stop.setupMoveConfig(self.moveClter)

def sendMoveCmdLoop(self, cmd):
self.moveCmdTimer.start(200)
self.moveCmdTimer.timeout.connect(lambda: self.moveClter.sendMoveCmd(cmd))
# self.sendMoveCmd(cmd)

def timerResetCmd(self):
self.moveCmdTimer.stop()
self.moveCmdTimer.timeout.disconnect()
self.moveClter.resetMoveCmd()

重写按键事件的代码:
class QMoveCltButton(QPushButton):
def __init__(self, parent=None):
super(QMoveCltButton, self).__init__(parent)
self.setFocusPolicy(Qt.StrongFocus)
self.keyPressedFlag = False

def _getCmd(self, enterKey):
if enterKey == Qt.Key_U:
cmd = 0
elif enterKey == Qt.Key_I:
cmd = 1
elif enterKey == Qt.Key_O:
cmd = 2
elif enterKey == Qt.Key_J:
cmd = 3
elif enterKey == Qt.Key_K:
cmd = 4
elif enterKey == Qt.Key_L:
cmd = 5
elif enterKey == Qt.Key_M:
cmd = 6
elif enterKey == Qt.Key_Comma:
cmd = 7
elif enterKey == Qt.Key_Period:
cmd = 8
else:
cmd = -1
return cmd

def setupMoveConfig(self, moveClter):
self.moveClter = moveClter

def keyPressEvent(self, event):
if event.isAutoRepeat():
if not self.keyPressedFlag:
self.keyPressedFlag = True
cmd = self._getCmd(event.key())
if not cmd == -1:
self.moveClter.sendMoveCmd(cmd)

def keyReleaseEvent(self, event):
if self.keyPressedFlag and not event.isAutoRepeat():
self.keyPressedFlag = False
cmd = self._getCmd(event.key())
if not cmd == -1:
self.moveClter.resetMoveCmd()
...全文
356 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
手无护鸡之力 2018-07-16
  • 打赏
  • 举报
回复
你应该重写MainWindow的 keyPressEvent吧, 而不是 按钮的

fyh82615919 2018-07-16
  • 打赏
  • 举报
回复
引用 1 楼 wn0112 的回复:
你应该重写MainWindow的 keyPressEvent吧, 而不是 按钮的

按大神的提示修改完了,功能基本对了,谢谢啦

37,743

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • WuKongSecurity@BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧