📄 qabstractspinbox.cpp
字号:
Pressing Qt::Key_Down will trigger a call to stepBy(-1), whereas pressing Qt::Key_Prior will trigger a call to stepBy(10). If you subclass QAbstractSpinBox you must reimplement this function. Note that this function is called even if the resulting value will be outside the bounds of minimum and maximum. It's this function's job to handle these situations.*/void QAbstractSpinBox::stepBy(int steps){ Q_D(QAbstractSpinBox); const QVariant old = d->value; QString tmp = d->edit->displayText(); int cursorPos = d->edit->cursorPosition(); bool dontstep = false; EmitPolicy e = EmitIfChanged; if (d->pendingEmit) { dontstep = validate(tmp, cursorPos) != QValidator::Acceptable; d->interpret(NeverEmit); if (d->value != old) e = AlwaysEmit; } if (!dontstep) { d->setValue(d->bound(d->value + (d->singleStep * steps), old, steps), e); } else if (e == AlwaysEmit) { d->emitSignals(e, old); } selectAll();}/*! This function returns a pointer to the line edit of the spin box.*/QLineEdit *QAbstractSpinBox::lineEdit() const{ Q_D(const QAbstractSpinBox); return d->edit;}/*! \fn void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit) Sets the line edit of the spinbox to be \a lineEdit instead of the current line edit widget. \a lineEdit can not be 0. QAbstractSpinBox takes ownership of the new lineEdit If QLineEdit::validator() for the \a lineEdit returns 0, the internal validator of the spinbox will be set on the line edit.*/void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit){ Q_D(QAbstractSpinBox); if (!lineEdit) { Q_ASSERT(lineEdit); return; } delete d->edit; d->edit = lineEdit; if (!d->edit->validator()) d->edit->setValidator(d->validator); if (d->edit->parent() != this) d->edit->setParent(this); d->edit->setFrame(false); d->edit->setAttribute(Qt::WA_InputMethodEnabled, false); d->edit->setFocusProxy(this); if (d->type != QVariant::Invalid) { connect(d->edit, SIGNAL(textChanged(QString)), this, SLOT(_q_editorTextChanged(QString))); connect(d->edit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(_q_editorCursorPositionChanged(int,int))); } QStyleOptionSpinBox opt = d->getStyleOption(); opt.subControls = QStyle::SC_SpinBoxEditField; d->edit->setGeometry(style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxEditField, this)); d->edit->setContextMenuPolicy(Qt::NoContextMenu); if (isVisible()) d->edit->show(); if (isVisible()) d->updateEdit();}/*! This function interprets the text of the spin box. If the value has changed since last interpretation it will emit signals.*/void QAbstractSpinBox::interpretText(){ Q_D(QAbstractSpinBox); d->interpret(EmitIfChanged);}/*! \reimp*/bool QAbstractSpinBox::event(QEvent *event){ Q_D(QAbstractSpinBox); switch (event->type()) { case QEvent::ApplicationLayoutDirectionChange: d->updateEdit(); break; case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) d->updateHoverControl(he->pos()); break; case QEvent::ShortcutOverride: if (d->edit->event(event)) return true; break; default: break; } return QWidget::event(event);}/*! \reimp*/void QAbstractSpinBox::showEvent(QShowEvent *){ Q_D(QAbstractSpinBox); d->reset(); d->updateEdit();}/*! \reimp*/void QAbstractSpinBox::changeEvent(QEvent *e){ Q_D(QAbstractSpinBox); switch(e->type()) { case QEvent::StyleChange: d->spinClickTimerInterval = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, 0, this); d->spinClickThresholdTimerInterval = thresholdTime; d->reset(); break; case QEvent::EnabledChange: if (!isEnabled()) { d->reset(); } break; case QEvent::ActivationChange: if (!isActiveWindow()){ d->reset(); if (d->pendingEmit) // pendingEmit can be true even if it hasn't changed. d->interpret(EmitIfChanged); // E.g. 10 to 10.0 } break; default: break; } QWidget::changeEvent(e);}/*! \reimp*/void QAbstractSpinBox::resizeEvent(QResizeEvent *e){ Q_D(QAbstractSpinBox); QWidget::resizeEvent(e); QStyleOptionSpinBox opt = d->getStyleOption(); opt.subControls = QStyle::SC_SpinBoxEditField; d->edit->setGeometry(style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxEditField, this)); update();}/*! \reimp*/QSize QAbstractSpinBox::sizeHint() const{ Q_D(const QAbstractSpinBox); ensurePolished(); const QFontMetrics fm(fontMetrics()); int h = d->edit->sizeHint().height(); int w = 0; QString s; s = d->prefix + d->textFromValue(d->minimum) + d->suffix + QLatin1Char(' '); s.truncate(18); w = qMax(w, fm.width(s)); s = d->prefix + d->textFromValue(d->maximum) + d->suffix + QLatin1Char(' '); s.truncate(18); w = qMax(w, fm.width(s)); if (d->specialValueText.size()) { s = d->specialValueText; w = qMax(w, fm.width(s)); } w += 2; // cursor blinking space QStyleOptionSpinBox opt = d->getStyleOption(); QSize hint(w, h); QSize extra(35, 6); opt.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxEditField, this).size(); // get closer to final result by repeating the calculation opt.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxEditField, this).size(); hint += extra; opt.rect = rect(); return style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this) .expandedTo(QApplication::globalStrut());}/*! \reimp*/QSize QAbstractSpinBox::minimumSizeHint() const{ Q_D(const QAbstractSpinBox); ensurePolished(); const QFontMetrics fm(fontMetrics()); int h = d->edit->minimumSizeHint().height(); int w = fm.width(QLatin1String("1000")); w += 2; // cursor blinking space QStyleOptionSpinBox opt = d->getStyleOption(); QSize hint(w, h); QSize extra(35, 6); opt.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxEditField, this).size(); // get closer to final result by repeating the calculation opt.rect.setSize(hint + extra); extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxEditField, this).size(); hint += extra; opt.rect = rect(); return style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this) .expandedTo(QApplication::globalStrut());}/*! \reimp*/void QAbstractSpinBox::paintEvent(QPaintEvent *){ Q_D(QAbstractSpinBox); QStyleOptionSpinBox opt = d->getStyleOption(); QPainter p(this); style()->drawComplexControl(QStyle::CC_SpinBox, &opt, &p, this);}/*! \reimp This function handles keyboard input. The following keys are handled specifically: \table \row \i Enter/Return \i This will reinterpret the text and emit a signal even if the value has not changed since last time a signal was emitted. \row \i Up \i This will invoke stepBy(1) \row \i Down \i This will invoke stepBy(-1) \row \i Page up \i This will invoke stepBy(10) \row \i Page down \i This will invoke stepBy(-10) \endtable*/void QAbstractSpinBox::keyPressEvent(QKeyEvent *e){ Q_D(QAbstractSpinBox); if (!e->text().isEmpty() && d->edit->cursorPosition() < d->prefix.size()) d->edit->setCursorPosition(d->prefix.size()); int steps = 1; switch(e->key()) { case Qt::Key_PageUp: case Qt::Key_PageDown: steps *= 10; case Qt::Key_Up: case Qt::Key_Down: {#ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) { // Reserve up/down for nav - use left/right for edit. if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down) { e->ignore(); return; } }#endif e->accept(); const bool up = (e->key() == Qt::Key_PageUp || e->key() == Qt::Key_Up); if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled))) return; if (!up) steps *= -1; if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) { d->buttonState = (Keyboard | (up ? Up : Down)); } stepBy(steps); return; }#ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Left: case Qt::Key_Right: if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { const bool up = (e->key() == Qt::Key_Right); if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled))) return; if (!up) steps *= -1; if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) { d->buttonState = (Keyboard | (up ? Up : Down)); } stepBy(steps); return; } break; case Qt::Key_Back: if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { e->ignore(); return; } break;#endif case Qt::Key_Enter: case Qt::Key_Return: d->interpret(AlwaysEmit); selectAll(); e->ignore(); emit editingFinished(); return;#ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: if (QApplication::keypadNavigationEnabled()) { // Toggles between left/right moving cursor and inc/dec. setEditFocus(!hasEditFocus()); if (!hasEditFocus()) selectAll(); } return;#endif#ifdef Q_WS_X11 // only X11 case Qt::Key_U: if (e->modifiers() & Qt::ControlModifier) { e->accept(); if (!isReadOnly()) clear(); return; } break;#else // Mac and Windows case Qt::Key_A: if (e->modifiers() & Qt::ControlModifier) { selectAll(); e->accept(); return; } break;#endif case Qt::Key_End: case Qt::Key_Home: if (e->modifiers() & Qt::ShiftModifier) { int currentPos = d->edit->cursorPosition(); const QString text = d->edit->displayText(); if (e->key() == Qt::Key_End) { if ((currentPos == 0 && !d->prefix.isEmpty()) || text.size() - d->suffix.size() <= currentPos) { break; // let lineedit handle this } else { d->edit->setSelection(currentPos, text.size() - d->suffix.size() - currentPos); } } else { if ((currentPos == text.size() && !d->suffix.isEmpty()) || currentPos <= d->prefix.size()) { break; // let lineedit handle this } else { d->edit->setSelection(currentPos, d->prefix.size() - currentPos); } } e->accept(); return; } break; case Qt::Key_Z: case Qt::Key_Y: if (e->modifiers() & Qt::ControlModifier) { e->ignore(); return; } break; default: break; } d->edit->event(e);}/*! \reimp*/void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *e){ Q_D(QAbstractSpinBox); if (d->buttonState & Keyboard && !e->isAutoRepeat() && style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) { d->reset(); } else { d->edit->event(e); }}/*! \reimp*/#ifndef QT_NO_WHEELEVENTvoid QAbstractSpinBox::wheelEvent(QWheelEvent *e){ const int steps = (e->delta() > 0 ? 1 : -1); if (stepEnabled() & (steps > 0 ? StepUpEnabled : StepDownEnabled)) stepBy(e->modifiers() & Qt::ControlModifier ? steps * 10 : steps); e->accept();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -