我希望通过箭头键使QDoubleSpinBox可控,即在按上时增加值,在选择框时按下时减小值。目前,我通过将singleStep设置为某个值来做到这一点。但是,在编辑字段时,我希望能够根据光标位置更改singleStep的值。
例如,对于带有两个小数位数的框,1.23,如果光标|位于第一个小数1.2|3,则希望按0.1增加或减少,但如果光标位于第二个十进制1.23|,则只希望增加/减少0.01。
注意:不确定是否相关,但我目前已将keyboardTracking设置为False,以避免通过数字键编辑值时发出信号。在使用错误键时,仍会发出这些值。
发布于 2022-02-18 18:38:54
在aavit's answer之后,我还在PyQt中重新定义了stepBy。由于我正在寻找一种适用于浮点数和负值的解决方案,所以我不得不处理一些特殊情况,并通过重新定义textFromValue来显示正值的+符号。以下解决方案对特殊情况作了评论:
import sys
from PyQt5.QtWidgets import QDoubleSpinBox, QMainWindow, QApplication, QLabel
class MyQDoubleSpinBox(QDoubleSpinBox):
def textFromValue(self, value):
# show + sign for positive values
text = super().textFromValue(value)
if value >= 0:
text = "+" + text
return text
def stepBy(self, steps):
cursor_position = self.lineEdit().cursorPosition()
# number of characters before the decimal separator including +/- sign
n_chars_before_sep = len(str(abs(int(self.value())))) + 1
if cursor_position == 0:
# set the cursor right of the +/- sign
self.lineEdit().setCursorPosition(1)
cursor_position = self.lineEdit().cursorPosition()
single_step = 10 ** (n_chars_before_sep - cursor_position)
# Handle decimal separator. Step should be 0.1 if cursor is at `1.|23` or
# `1.2|3`.
if cursor_position >= n_chars_before_sep + 2:
single_step = 10 * single_step
# Change single step and perform the step
self.setSingleStep(single_step)
super().stepBy(steps)
# Undo selection of the whole text.
self.lineEdit().deselect()
# Handle cases where the number of characters before the decimal separator
# changes. Step size should remain the same.
new_n_chars_before_sep = len(str(abs(int(self.value())))) + 1
if new_n_chars_before_sep < n_chars_before_sep:
cursor_position -= 1
elif new_n_chars_before_sep > n_chars_before_sep:
cursor_position += 1
self.lineEdit().setCursorPosition(cursor_position)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100, 100, 600, 400)
self.UiComponents()
self.show()
def UiComponents(self):
self.spin = MyQDoubleSpinBox(self)
self.spin.setGeometry(100, 100, 150, 40)
self.spin.setRange(-10000, 10000)
self.spin.setValue(50)
self.spin.setKeyboardTracking(False)
if __name__ == "__main__":
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())发布于 2022-02-18 08:28:29
实现这一目标的最简单方法可能是创建QDoubleSpinBox的子类并覆盖虚拟stepBy()方法。这在每次值被提升或下降时都会被调用。下面是一个简单的示例,它演示了如何对整数旋转框执行此操作。对于浮点值,只需将singleStep大小固定在最小的十进制步长,并在考虑小数点的情况下,在stepBy()中更仔细地解析文本。
class MySpinBox : public QSpinBox
{
public:
explicit MySpinBox(QWidget *parent = nullptr)
: QSpinBox(parent) {
setMaximum(9999);
setValue(5000);
};
void stepBy(int steps) override {
const int cursorPos = qMax(lineEdit()->cursorPosition(), 1);
const int textLen = lineEdit()->text().length();
for (int i = textLen - cursorPos; i > 0; i--)
steps *= 10;
QAbstractSpinBox::stepBy(steps);
lineEdit()->setCursorPosition(cursorPos);
}
};https://stackoverflow.com/questions/71137584
复制相似问题