I would like to make a spin-box which only is editable after double-clicking in the digit display area.
My attempt below disables the focus in all cases except when the increment/decrement buttons are pressed.
I want increment/decrement to perform the actions without stealing the focus. I do want the the normal blinking cursor and edit functionality when the text area is double-clicked.
After editing, the widget should release focus when another widget is clicked, or enter is pressed.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
event_dict = {v: k for k, v in QtCore.QEvent.__dict__.items() if isinstance(v, int)}
noisy_events = [
'Paint',
'Show',
'Move',
'Resize',
'DynamicPropertyChange',
'PolishRequest',
'Polish',
'ChildPolished',
'HoverMove',
'HoverEnter',
'HoverLeave',
'ChildAdded',
'ChildRemoved',
]
class ClickableSpinBox(QtWidgets.QDoubleSpinBox):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.installEventFilter(self)
self.setFocusPolicy(Qt.NoFocus)
def eventFilter(self, a0: 'QObject', a1: 'QEvent') -> bool:
if a0 is not self:
return super().eventFilter(a0, a1)
if a1.type() == QtCore.QEvent.FocusAboutToChange:
print("intercepted focus about to change")
return True
if a1.type() == QtCore.QEvent.FocusIn:
print("intercepted focus in")
return True
if a1.type() == QtCore.QEvent.MouseButtonPress:
print("intercepted mouse press")
#return True
elif a1.type() == QtCore.QEvent.MouseButtonDblClick:
print("intercepted double click")
self.setFocus()
else:
if a1.type() in event_dict:
evt_name = event_dict[a1.type()]
if evt_name not in noisy_events:
print(evt_name)
else:
pass
#print(f"Unknown event type {a1.type()}")
return super().eventFilter(a0, a1)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
w = QtWidgets.QWidget()
l = QtWidgets.QHBoxLayout()
l.addWidget(ClickableSpinBox())
l.addWidget(ClickableSpinBox())
l.addWidget(QtWidgets.QDoubleSpinBox())
w.setLayout(l)
w.show()
app.exec_()
Edit:
To let the mouse-scroll function and the increase/decrease buttons working
I make the
QLineEditinside of theQDoubleSpinBoxto be enabled/disabled when you double click inside it or in the borders of the SpinBox. With this, you can still change the value inside it with the mouse-scroll or with the buttons. Here is your code modified:The result with the
QLineEditdisabled and the buttons enabled:To let ONLY the mouse-scroll function
You just have to remove the buttons from the code above, using
setButtonSymbols().The result with the buttons "disabled":
Previous Answer (before the Edit)
I have a tricky solution, and it consists of Enable/Disable the customs spin boxes you created. With this, the spinboxes will be enabled (and editable) only when you double-clicked on them, and when you lose focus on them they will be disabled automatically, passing the focus to the enabled SpinBox.
The reason I did that is that when the SpinBox is enabled, the DoubleClick event will only be triggered when you double click on the borders or on the increment/decrement buttons. Disabling them will do the trick because the double click event will be triggered wherever you press inside the SpinBox.
Here is your code with my modifications: (there are comments inside te code to help you understand what I did)
And some screenshots of that code running: