如何强制键盘聚焦于特定的 widget/QGroupBox (PyQt5)?
How to force keyboard focus on a specific widget/QGroupBox (PyQt5)?
我正在开发一个 GUI,我遇到了一个问题,有时按下 'enter' 键会使多个小部件发送它们的信号。最奇怪的部分是它有时会发生,有时不会。最主要的是,我不能保证一直只关注一个QGroupBox
。
这是一个比较简单的例子。如果你 运行 它并输入文本,然后点击 'enter',将执行两个函数(下图)。
# -*- coding: utf-8 -*-
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QComboBox, QStyleFactory, QDialog, QTextEdit,
QGroupBox, QLabel, QLineEdit, QGridLayout, QPushButton, QVBoxLayout)
import sys
class GrblGUI(QDialog):
class PositionDescriber:
""" Label and widget associated for each axis. Save some writing later """
def __init__(self, labelText, initVal=0.0):
self.posLabel = QLabel(labelText)
self.value = initVal
self.posWidget = QLineEdit(str(self.value))
def __init__(self, parent=None):
""" Initializes the GUI and all widgets within.
Creates the general layout
"""
super(GrblGUI, self).__init__(parent)
self.originalPalette = QApplication.palette()
self.axes = [ self.PositionDescriber("X pos : "),
self.PositionDescriber("Y pos : "),
self.PositionDescriber("Z pos : "),
self.PositionDescriber("A pos : "),
self.PositionDescriber("B pos : ")]
self.size = range(len(self.axes))
self.ports = ["None"]
# Creating widget within panels
self.createConnectToCOM()
self.createPositionControlPanel()
self.createPushButtonsPanel()
self.createMessageHistory()
mainLayout = QGridLayout()
mainLayout.addWidget(self.connectToCOM, 0, 0, 1, 2)
mainLayout.addWidget(self.positionControlPanel, 1, 0)
mainLayout.addWidget(self.pushButtonsPanel, 0, 2, 2, 1)
mainLayout.addWidget(self.messageHistory, 1, 1)
mainLayout.setRowStretch(1, 1)
self.setLayout(mainLayout)
self.setWindowTitle("minimal")
QApplication.setStyle(QStyleFactory.create('Fusion'))
QApplication.setPalette(QApplication.style().standardPalette())
"""
Creation of panels, widgets, and associated layouts
"""
def createConnectToCOM(self):
self.connectToCOM = QGroupBox()
self.availableDevicesScroll = QComboBox()
for item in self.ports:
self.availableDevicesScroll.addItem(item)
connectLabel = QLabel("Connect to device :")
self.updatePushButton = QPushButton("Update")
self.updatePushButton.setDefault(True)
self.connectPushButton = QPushButton("Connect")
self.connectPushButton.setDefault(True)
self.updatePushButton.clicked.connect(self.updateAvailableCOM)
self.connectPushButton.clicked.connect(self.connectToPort)
layout = QGridLayout()
layout.addWidget(connectLabel, 0, 0)
layout.addWidget(self.availableDevicesScroll, 1, 0)
layout.addWidget(self.updatePushButton, 0, 1)
layout.addWidget(self.connectPushButton, 1, 1)
layout.setColumnStretch(0, 1)
self.connectToCOM.setLayout(layout)
def createPositionControlPanel(self):
self.positionControlPanel = QGroupBox("Position Control Panel : ")
for i in self.size:
self.axes[i].posWidget.returnPressed.connect(self.registerInput)
layout = QGridLayout()
for i in self.size:
layout.addWidget(self.axes[i].posLabel, i, 0)
for i in self.size:
layout.addWidget(self.axes[i].posWidget, i, 1)
sendPushButton = QPushButton("Send to pos")
sendPushButton.setDefault(True)
sendPushButton.clicked.connect(self.sendToPos)
layout.addWidget(sendPushButton, len(self.axes), 2, 1, 2)
layout.setRowStretch(6, 1)
self.positionControlPanel.setLayout(layout)
def createPushButtonsPanel(self):
self.pushButtonsPanel = QGroupBox("Things you may want to do : ")
self.homingPushButton = QPushButton("Homing")
self.homingPushButton.setDefault(True)
self.homingPushButton.clicked.connect(self.homing)
recPosPushButton = QPushButton("Record current pos")
recPosPushButton.setDefault(True)
recPosPushButton.clicked.connect(self.recordPosition)
layout = QVBoxLayout()
layout.setSpacing(20)
layout.addWidget(self.homingPushButton)
layout.addWidget(recPosPushButton)
layout.addStretch(1)
self.pushButtonsPanel.setLayout(layout)
def createMessageHistory(self):
self.messageHistory = QGroupBox("Message history : ")
self.textEdit = QTextEdit()
self.textEdit.setReadOnly(True)
self.textEdit.setPlainText("")
layout = QVBoxLayout()
layout.addWidget(self.textEdit)
self.messageHistory.setLayout(layout)
"""
Methods to call
"""
def connectToPort(self):
self.textEdit.append("connectToPort")
def updateAvailableCOM(self):
self.textEdit.append("updateAvailableCOM")
def registerInput(self):
self.textEdit.append("registerInput")
def homing(self):
self.textEdit.append("homing")
def recordPosition(self):
self.textEdit.append("recordPosition")
def sendToPos(self):
self.textEdit.append("sendToPos")
if __name__ == '__main__':
app = QApplication(sys.argv)
gallery = GrblGUI()
gallery.show()
app.exec()
# sys.exit(appctxt.app.exec())
输入文字后的结果:
我尝试了不同的方法,例如 setFocusPolicy(Qt.NoFocus)
或 setFocus()
,但没有用。有什么想法吗?
@musicamante 发现,这与
密切相关
最简单的答案是继承 QWidget
而不是 QDialog
,因为不再有默认按钮。
问题来自default
and autoDefault
properties of QPushButton in combination with the usage of QDialog,结果如下
- 如果
autoDefault
是 True
,一个按钮成为可能的 default
按钮;
- QPushButton 的
autoDefault
属性 是 False
,除非它 is/becomes QDialog 的子级(甚至是间接的);
不接受的小部件接收的事件会自动传播到其父级,在父级层次结构中向上,直到一个小部件接受 接受它或到达顶级小部件。
QLineEdit 默认 处理 return 按键,但 不 接受它,这意味着它知道键已被按下(因为它可以发出 returnPressed
信号)但不会处理,因此将其传播给父级。
考虑到上述情况,不需要的行为是按键事件也被 QDialog 接收,因此有多种可能性,具体取决于要求。
使用 QWidget 而不是 QDialog
这是最简单的选择,但您可能仍然需要 QDialog 来实现其功能:exec
事件循环、accepted/rejected
信号和结果接口,或者只是为了简化模态
将所有按钮的default
属性设置为False
显然,您可以将每个按钮的 autoDefault
属性 设置为 False
,但更简单的解决方案是使用一个循环遍历所有 QPushButton 实例的循环,这应该是在我们确定会调用的覆盖中实现,例如 exec
或者,也许更好,showEvent
:
class Dialog(QtWidgets.QDialog)
# ...
def showEvent(self, event):
super().showEvent(event)
if not event.spontaneous():
for btn in self.findChildren(QtWidgets.QPushButton):
if btn.default():
btn.setDefault(False)
if btn.autoDefault():
btn.setAutoDefault(False)
不过,这可能会成为一个问题,因为有时您可能仍然想使用该功能:例如,如果您有一个 tab/stacked 小部件,并且您想避免使用 return 功能在一个有行编辑的页面中,但在另一个只有一个按钮(如向导)的页面中没有。
忽略对话框中的 Return
键
重写 keyPressEvent
,如果键是 not return,则仅调用基础实现 或输入(这与上面有同样的问题,因为它完全禁用了该功能):
class Dialog(QtWidgets.QDialog)
# ...
def keyPressEvent(self, event):
if event.key() not in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
super().keyPressEvent(event)
在行编辑中接受按键事件
这可能是一种更合适的方法,因为它解决了 来源 的问题:如果按下 return/enter 键,则认为事件在 QLineEdit 中被接受.这只能在子类中完成:
class LineEdit(QtWidgets.QLineEdit):
def keyPressEvent(self, event):
super().keyPressEvent(event)
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
event.accept()
可能对整个表单使用 eventFilter
是您的解决方案:
from QtCore import QEvent
- 在
class GrblGUI
中定义 eventFilter(self, obj, event)
并在 Qt.Key_Enter
分支下放置您想要的回车键按下。
- 注册事件过滤器
app.installEventFilter(gallery)
下面修改示例(小心,我在示例中切换到 PySide2,您可以轻松地再次切换回 PyQt5):
# -*- coding: utf-8 -*-
from PySide2.QtCore import Qt, QEvent # Step 1 - import QEvent
from PySide2.QtWidgets import QApplication, QComboBox, QStyleFactory, QDialog, QTextEdit
from PySide2.QtWidgets import QGroupBox, QLabel, QLineEdit, QGridLayout, QPushButton, QVBoxLayout
import sys
class GrblGUI(QDialog):
class PositionDescriber:
""" Label and widget associated for each axis. Save some writing later """
def __init__(self, labelText, initVal=0.0):
self.posLabel = QLabel(labelText)
self.value = initVal
self.posWidget = QLineEdit(str(self.value))
def __init__(self, parent=None):
""" Initializes the GUI and all widgets within.
Creates the general layout
"""
super(GrblGUI, self).__init__(parent)
self.originalPalette = QApplication.palette()
self.axes = [ self.PositionDescriber("X pos : "),
self.PositionDescriber("Y pos : "),
self.PositionDescriber("Z pos : "),
self.PositionDescriber("A pos : "),
self.PositionDescriber("B pos : ")]
self.size = range(len(self.axes))
self.ports = ["None"]
# Creating widget within panels
self.createConnectToCOM()
self.createPositionControlPanel()
self.createPushButtonsPanel()
self.createMessageHistory()
mainLayout = QGridLayout()
mainLayout.addWidget(self.connectToCOM, 0, 0, 1, 2)
mainLayout.addWidget(self.positionControlPanel, 1, 0)
mainLayout.addWidget(self.pushButtonsPanel, 0, 2, 2, 1)
mainLayout.addWidget(self.messageHistory, 1, 1)
mainLayout.setRowStretch(1, 1)
self.setLayout(mainLayout)
self.setWindowTitle("minimal")
QApplication.setStyle(QStyleFactory.create('Fusion'))
QApplication.setPalette(QApplication.style().standardPalette())
"""
Creation of panels, widgets, and associated layouts
"""
def eventFilter(self, obj, event): # Step 2 - declare QEvent filter
if event.type() == QEvent.KeyPress:
if (event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return):
self.textEdit.append("***DEBUG: Enter pressed")
# Step 2 Place callback you want to process key press
event.accept() # block event propagation to other widgets
return True
return False
def createConnectToCOM(self):
self.connectToCOM = QGroupBox()
self.availableDevicesScroll = QComboBox()
for item in self.ports:
self.availableDevicesScroll.addItem(item)
connectLabel = QLabel("Connect to device :")
self.updatePushButton = QPushButton("Update")
self.updatePushButton.setDefault(True)
self.connectPushButton = QPushButton("Connect")
self.connectPushButton.setDefault(True)
self.updatePushButton.clicked.connect(self.updateAvailableCOM)
self.connectPushButton.clicked.connect(self.connectToPort)
layout = QGridLayout()
layout.addWidget(connectLabel, 0, 0)
layout.addWidget(self.availableDevicesScroll, 1, 0)
layout.addWidget(self.updatePushButton, 0, 1)
layout.addWidget(self.connectPushButton, 1, 1)
layout.setColumnStretch(0, 1)
self.connectToCOM.setLayout(layout)
def createPositionControlPanel(self):
self.positionControlPanel = QGroupBox("Position Control Panel : ")
for i in self.size:
self.axes[i].posWidget.returnPressed.connect(self.registerInput)
layout = QGridLayout()
for i in self.size:
layout.addWidget(self.axes[i].posLabel, i, 0)
for i in self.size:
layout.addWidget(self.axes[i].posWidget, i, 1)
sendPushButton = QPushButton("Send to pos")
sendPushButton.setDefault(True)
sendPushButton.clicked.connect(self.sendToPos)
layout.addWidget(sendPushButton, len(self.axes), 2, 1, 2)
layout.setRowStretch(6, 1)
self.positionControlPanel.setLayout(layout)
def createPushButtonsPanel(self):
self.pushButtonsPanel = QGroupBox("Things you may want to do : ")
self.homingPushButton = QPushButton("Homing")
#self.homingPushButton.setFocusPolicy(Qt.StrongFocus); #!!!
self.homingPushButton.setDefault(True)
self.homingPushButton.clicked.connect(self.homing)
recPosPushButton = QPushButton("Record current pos")
recPosPushButton.setDefault(True)
recPosPushButton.clicked.connect(self.recordPosition)
layout = QVBoxLayout()
layout.setSpacing(20)
layout.addWidget(self.homingPushButton)
layout.addWidget(recPosPushButton)
layout.addStretch(1)
self.pushButtonsPanel.setLayout(layout)
def createMessageHistory(self):
self.messageHistory = QGroupBox("Message history : ")
self.textEdit = QTextEdit()
self.textEdit.setReadOnly(True)
self.textEdit.setPlainText("")
layout = QVBoxLayout()
layout.addWidget(self.textEdit)
self.messageHistory.setLayout(layout)
"""
Methods to call
"""
def connectToPort(self):
self.textEdit.append("connectToPort")
def updateAvailableCOM(self):
self.textEdit.append("updateAvailableCOM")
def registerInput(self):
self.textEdit.append("registerInput")
def homing(self):
self.textEdit.append("homing")
def recordPosition(self):
self.textEdit.append("recordPosition")
def sendToPos(self):
self.textEdit.append("sendToPos")
if __name__ == '__main__':
app = QApplication(sys.argv)
gallery = GrblGUI()
gallery.show()
app.installEventFilter(gallery) # Step 4 - register event filter in app
app.exec_()
我正在开发一个 GUI,我遇到了一个问题,有时按下 'enter' 键会使多个小部件发送它们的信号。最奇怪的部分是它有时会发生,有时不会。最主要的是,我不能保证一直只关注一个QGroupBox
。
这是一个比较简单的例子。如果你 运行 它并输入文本,然后点击 'enter',将执行两个函数(下图)。
# -*- coding: utf-8 -*-
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QComboBox, QStyleFactory, QDialog, QTextEdit,
QGroupBox, QLabel, QLineEdit, QGridLayout, QPushButton, QVBoxLayout)
import sys
class GrblGUI(QDialog):
class PositionDescriber:
""" Label and widget associated for each axis. Save some writing later """
def __init__(self, labelText, initVal=0.0):
self.posLabel = QLabel(labelText)
self.value = initVal
self.posWidget = QLineEdit(str(self.value))
def __init__(self, parent=None):
""" Initializes the GUI and all widgets within.
Creates the general layout
"""
super(GrblGUI, self).__init__(parent)
self.originalPalette = QApplication.palette()
self.axes = [ self.PositionDescriber("X pos : "),
self.PositionDescriber("Y pos : "),
self.PositionDescriber("Z pos : "),
self.PositionDescriber("A pos : "),
self.PositionDescriber("B pos : ")]
self.size = range(len(self.axes))
self.ports = ["None"]
# Creating widget within panels
self.createConnectToCOM()
self.createPositionControlPanel()
self.createPushButtonsPanel()
self.createMessageHistory()
mainLayout = QGridLayout()
mainLayout.addWidget(self.connectToCOM, 0, 0, 1, 2)
mainLayout.addWidget(self.positionControlPanel, 1, 0)
mainLayout.addWidget(self.pushButtonsPanel, 0, 2, 2, 1)
mainLayout.addWidget(self.messageHistory, 1, 1)
mainLayout.setRowStretch(1, 1)
self.setLayout(mainLayout)
self.setWindowTitle("minimal")
QApplication.setStyle(QStyleFactory.create('Fusion'))
QApplication.setPalette(QApplication.style().standardPalette())
"""
Creation of panels, widgets, and associated layouts
"""
def createConnectToCOM(self):
self.connectToCOM = QGroupBox()
self.availableDevicesScroll = QComboBox()
for item in self.ports:
self.availableDevicesScroll.addItem(item)
connectLabel = QLabel("Connect to device :")
self.updatePushButton = QPushButton("Update")
self.updatePushButton.setDefault(True)
self.connectPushButton = QPushButton("Connect")
self.connectPushButton.setDefault(True)
self.updatePushButton.clicked.connect(self.updateAvailableCOM)
self.connectPushButton.clicked.connect(self.connectToPort)
layout = QGridLayout()
layout.addWidget(connectLabel, 0, 0)
layout.addWidget(self.availableDevicesScroll, 1, 0)
layout.addWidget(self.updatePushButton, 0, 1)
layout.addWidget(self.connectPushButton, 1, 1)
layout.setColumnStretch(0, 1)
self.connectToCOM.setLayout(layout)
def createPositionControlPanel(self):
self.positionControlPanel = QGroupBox("Position Control Panel : ")
for i in self.size:
self.axes[i].posWidget.returnPressed.connect(self.registerInput)
layout = QGridLayout()
for i in self.size:
layout.addWidget(self.axes[i].posLabel, i, 0)
for i in self.size:
layout.addWidget(self.axes[i].posWidget, i, 1)
sendPushButton = QPushButton("Send to pos")
sendPushButton.setDefault(True)
sendPushButton.clicked.connect(self.sendToPos)
layout.addWidget(sendPushButton, len(self.axes), 2, 1, 2)
layout.setRowStretch(6, 1)
self.positionControlPanel.setLayout(layout)
def createPushButtonsPanel(self):
self.pushButtonsPanel = QGroupBox("Things you may want to do : ")
self.homingPushButton = QPushButton("Homing")
self.homingPushButton.setDefault(True)
self.homingPushButton.clicked.connect(self.homing)
recPosPushButton = QPushButton("Record current pos")
recPosPushButton.setDefault(True)
recPosPushButton.clicked.connect(self.recordPosition)
layout = QVBoxLayout()
layout.setSpacing(20)
layout.addWidget(self.homingPushButton)
layout.addWidget(recPosPushButton)
layout.addStretch(1)
self.pushButtonsPanel.setLayout(layout)
def createMessageHistory(self):
self.messageHistory = QGroupBox("Message history : ")
self.textEdit = QTextEdit()
self.textEdit.setReadOnly(True)
self.textEdit.setPlainText("")
layout = QVBoxLayout()
layout.addWidget(self.textEdit)
self.messageHistory.setLayout(layout)
"""
Methods to call
"""
def connectToPort(self):
self.textEdit.append("connectToPort")
def updateAvailableCOM(self):
self.textEdit.append("updateAvailableCOM")
def registerInput(self):
self.textEdit.append("registerInput")
def homing(self):
self.textEdit.append("homing")
def recordPosition(self):
self.textEdit.append("recordPosition")
def sendToPos(self):
self.textEdit.append("sendToPos")
if __name__ == '__main__':
app = QApplication(sys.argv)
gallery = GrblGUI()
gallery.show()
app.exec()
# sys.exit(appctxt.app.exec())
输入文字后的结果:
我尝试了不同的方法,例如 setFocusPolicy(Qt.NoFocus)
或 setFocus()
,但没有用。有什么想法吗?
@musicamante 发现,这与
最简单的答案是继承 QWidget
而不是 QDialog
,因为不再有默认按钮。
问题来自default
and autoDefault
properties of QPushButton in combination with the usage of QDialog,结果如下
- 如果
autoDefault
是True
,一个按钮成为可能的default
按钮; - QPushButton 的
autoDefault
属性 是False
,除非它 is/becomes QDialog 的子级(甚至是间接的);
不接受的小部件接收的事件会自动传播到其父级,在父级层次结构中向上,直到一个小部件接受 接受它或到达顶级小部件。
QLineEdit 默认 处理 return 按键,但 不 接受它,这意味着它知道键已被按下(因为它可以发出 returnPressed
信号)但不会处理,因此将其传播给父级。
考虑到上述情况,不需要的行为是按键事件也被 QDialog 接收,因此有多种可能性,具体取决于要求。
使用 QWidget 而不是 QDialog
这是最简单的选择,但您可能仍然需要 QDialog 来实现其功能:exec
事件循环、accepted/rejected
信号和结果接口,或者只是为了简化模态
将所有按钮的default
属性设置为False
显然,您可以将每个按钮的 autoDefault
属性 设置为 False
,但更简单的解决方案是使用一个循环遍历所有 QPushButton 实例的循环,这应该是在我们确定会调用的覆盖中实现,例如 exec
或者,也许更好,showEvent
:
class Dialog(QtWidgets.QDialog)
# ...
def showEvent(self, event):
super().showEvent(event)
if not event.spontaneous():
for btn in self.findChildren(QtWidgets.QPushButton):
if btn.default():
btn.setDefault(False)
if btn.autoDefault():
btn.setAutoDefault(False)
不过,这可能会成为一个问题,因为有时您可能仍然想使用该功能:例如,如果您有一个 tab/stacked 小部件,并且您想避免使用 return 功能在一个有行编辑的页面中,但在另一个只有一个按钮(如向导)的页面中没有。
忽略对话框中的 Return
键
重写 keyPressEvent
,如果键是 not return,则仅调用基础实现 或输入(这与上面有同样的问题,因为它完全禁用了该功能):
class Dialog(QtWidgets.QDialog)
# ...
def keyPressEvent(self, event):
if event.key() not in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
super().keyPressEvent(event)
在行编辑中接受按键事件
这可能是一种更合适的方法,因为它解决了 来源 的问题:如果按下 return/enter 键,则认为事件在 QLineEdit 中被接受.这只能在子类中完成:
class LineEdit(QtWidgets.QLineEdit):
def keyPressEvent(self, event):
super().keyPressEvent(event)
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
event.accept()
可能对整个表单使用 eventFilter
是您的解决方案:
from QtCore import QEvent
- 在
class GrblGUI
中定义eventFilter(self, obj, event)
并在Qt.Key_Enter
分支下放置您想要的回车键按下。 - 注册事件过滤器
app.installEventFilter(gallery)
下面修改示例(小心,我在示例中切换到 PySide2,您可以轻松地再次切换回 PyQt5):
# -*- coding: utf-8 -*-
from PySide2.QtCore import Qt, QEvent # Step 1 - import QEvent
from PySide2.QtWidgets import QApplication, QComboBox, QStyleFactory, QDialog, QTextEdit
from PySide2.QtWidgets import QGroupBox, QLabel, QLineEdit, QGridLayout, QPushButton, QVBoxLayout
import sys
class GrblGUI(QDialog):
class PositionDescriber:
""" Label and widget associated for each axis. Save some writing later """
def __init__(self, labelText, initVal=0.0):
self.posLabel = QLabel(labelText)
self.value = initVal
self.posWidget = QLineEdit(str(self.value))
def __init__(self, parent=None):
""" Initializes the GUI and all widgets within.
Creates the general layout
"""
super(GrblGUI, self).__init__(parent)
self.originalPalette = QApplication.palette()
self.axes = [ self.PositionDescriber("X pos : "),
self.PositionDescriber("Y pos : "),
self.PositionDescriber("Z pos : "),
self.PositionDescriber("A pos : "),
self.PositionDescriber("B pos : ")]
self.size = range(len(self.axes))
self.ports = ["None"]
# Creating widget within panels
self.createConnectToCOM()
self.createPositionControlPanel()
self.createPushButtonsPanel()
self.createMessageHistory()
mainLayout = QGridLayout()
mainLayout.addWidget(self.connectToCOM, 0, 0, 1, 2)
mainLayout.addWidget(self.positionControlPanel, 1, 0)
mainLayout.addWidget(self.pushButtonsPanel, 0, 2, 2, 1)
mainLayout.addWidget(self.messageHistory, 1, 1)
mainLayout.setRowStretch(1, 1)
self.setLayout(mainLayout)
self.setWindowTitle("minimal")
QApplication.setStyle(QStyleFactory.create('Fusion'))
QApplication.setPalette(QApplication.style().standardPalette())
"""
Creation of panels, widgets, and associated layouts
"""
def eventFilter(self, obj, event): # Step 2 - declare QEvent filter
if event.type() == QEvent.KeyPress:
if (event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return):
self.textEdit.append("***DEBUG: Enter pressed")
# Step 2 Place callback you want to process key press
event.accept() # block event propagation to other widgets
return True
return False
def createConnectToCOM(self):
self.connectToCOM = QGroupBox()
self.availableDevicesScroll = QComboBox()
for item in self.ports:
self.availableDevicesScroll.addItem(item)
connectLabel = QLabel("Connect to device :")
self.updatePushButton = QPushButton("Update")
self.updatePushButton.setDefault(True)
self.connectPushButton = QPushButton("Connect")
self.connectPushButton.setDefault(True)
self.updatePushButton.clicked.connect(self.updateAvailableCOM)
self.connectPushButton.clicked.connect(self.connectToPort)
layout = QGridLayout()
layout.addWidget(connectLabel, 0, 0)
layout.addWidget(self.availableDevicesScroll, 1, 0)
layout.addWidget(self.updatePushButton, 0, 1)
layout.addWidget(self.connectPushButton, 1, 1)
layout.setColumnStretch(0, 1)
self.connectToCOM.setLayout(layout)
def createPositionControlPanel(self):
self.positionControlPanel = QGroupBox("Position Control Panel : ")
for i in self.size:
self.axes[i].posWidget.returnPressed.connect(self.registerInput)
layout = QGridLayout()
for i in self.size:
layout.addWidget(self.axes[i].posLabel, i, 0)
for i in self.size:
layout.addWidget(self.axes[i].posWidget, i, 1)
sendPushButton = QPushButton("Send to pos")
sendPushButton.setDefault(True)
sendPushButton.clicked.connect(self.sendToPos)
layout.addWidget(sendPushButton, len(self.axes), 2, 1, 2)
layout.setRowStretch(6, 1)
self.positionControlPanel.setLayout(layout)
def createPushButtonsPanel(self):
self.pushButtonsPanel = QGroupBox("Things you may want to do : ")
self.homingPushButton = QPushButton("Homing")
#self.homingPushButton.setFocusPolicy(Qt.StrongFocus); #!!!
self.homingPushButton.setDefault(True)
self.homingPushButton.clicked.connect(self.homing)
recPosPushButton = QPushButton("Record current pos")
recPosPushButton.setDefault(True)
recPosPushButton.clicked.connect(self.recordPosition)
layout = QVBoxLayout()
layout.setSpacing(20)
layout.addWidget(self.homingPushButton)
layout.addWidget(recPosPushButton)
layout.addStretch(1)
self.pushButtonsPanel.setLayout(layout)
def createMessageHistory(self):
self.messageHistory = QGroupBox("Message history : ")
self.textEdit = QTextEdit()
self.textEdit.setReadOnly(True)
self.textEdit.setPlainText("")
layout = QVBoxLayout()
layout.addWidget(self.textEdit)
self.messageHistory.setLayout(layout)
"""
Methods to call
"""
def connectToPort(self):
self.textEdit.append("connectToPort")
def updateAvailableCOM(self):
self.textEdit.append("updateAvailableCOM")
def registerInput(self):
self.textEdit.append("registerInput")
def homing(self):
self.textEdit.append("homing")
def recordPosition(self):
self.textEdit.append("recordPosition")
def sendToPos(self):
self.textEdit.append("sendToPos")
if __name__ == '__main__':
app = QApplication(sys.argv)
gallery = GrblGUI()
gallery.show()
app.installEventFilter(gallery) # Step 4 - register event filter in app
app.exec_()