我不知道该技术的术语是否顺利,但是听起来最容易理解。因此,让我们解释一下我想要的。
我有两个按钮:一个+和一个-以及中间的一个数字10。
我的范围是1到300。我不希望用户单击289次以转到300。我希望当用户按住我的案例的手指按住+按钮时,例如走5秒钟。并快速更改它。
是否可以通过单击QPushButton的SLOT来实现,或者我需要找到其他解决方案并编写自定义窗口小部件。 而要做的就是已经实现了某些功能或小部件
答案 0 :(得分:2)
创建一个包含两个按钮(添加和子按钮)和标签的小部件。使用QPushButton::pressed
信号可以知道何时按下按钮并按下QPushButton::released
。
按下按钮时,定义方向(子或添加)并以较高的初始间隔触发计时器。每次经过计时器(QTimer::timeout
)时,请增加/减少与方向有关的值,并减少计时器的间隔。
一个简单的例子:
class SpinBox: public QWidget
{
Q_OBJECT
public:
SpinBox(QWidget* parent=nullptr): QWidget(parent),
value(0),
min(0),
max(500),
direction(Forward),
timer(new QTimer(this)),
addButton(new QPushButton("+")),
subButton(new QPushButton("-")),
text(new QLabel("0"))
{
timer->setInterval(500);
connect(addButton, &QPushButton::pressed, this, &SpinBox::forward);
connect(subButton, &QPushButton::pressed, this, &SpinBox::backward);
connect(addButton, &QPushButton::released, timer, &QTimer::stop);
connect(subButton, &QPushButton::released, timer, &QTimer::stop);
connect(timer, &QTimer::timeout, this, &SpinBox::updateValue);
QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(subButton);
layout->addWidget(text);
layout->addWidget(addButton);
}
private slots:
void updateValue()
{
if (direction == Forward)
{
++value;
if (value == max)
timer->stop();
}
else
{
--value;
if (value == min)
timer->stop();
}
text->setText(QString::number(value));
timer->setInterval(std::max(10.0, float(timer->interval()) * 0.9));
update();
}
void backward()
{
direction = Backward;
timer->start();
}
void forward()
{
direction = Forward;
timer->start();
}
private:
enum Direction
{
Forward,
Backward
};
int value;
int min;
int max;
Direction direction;
QTimer* timer;
QPushButton* addButton;
QPushButton* subButton;
QLabel* text;
};
您还可以通过使用mousePressEvent
和mouseReleaseEvent
使用普通窗口小部件执行相同的操作。对于自定义样式的小部件可能很有用,可以避免与内部布局有关的问题:
class SpinBox: public QWidget
{
Q_OBJECT
public:
SpinBox(QWidget* parent=nullptr): QWidget(parent),
value(0),
min(0),
max(500),
direction(Forward),
timer(new QTimer(this))
{
timer->setInterval(500);
connect(timer, &QTimer::timeout, this, &SpinBox::updateValue);
}
private slots:
void updateValue()
{
if (direction == Forward)
{
++value;
if (value == max)
timer->stop();
}
else
{
--value;
if (value == min)
timer->stop();
}
timer->setInterval(std::max(10.0, float(timer->interval()) * 0.9));
update();
}
private:
enum Direction
{
Forward,
Backward
};
virtual void paintEvent(QPaintEvent* event) override
{
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::gray);
painter.drawRect(subButtonRect());
painter.drawRect(addButtonRect());
painter.setPen(Qt::black);
painter.setFont(QFont("Helvetica", 20));
painter.drawText(addButtonRect(), Qt::AlignCenter, "+");
painter.drawText(subButtonRect(), Qt::AlignCenter, "-");
painter.drawText(textRect(), Qt::AlignCenter, QString::number(value));
}
QRect addButtonRect()
{
return QRect(width() - 30, 0, 30, height());
}
QRect subButtonRect()
{
return QRect(0, 0, 30, height());
}
QRect textRect()
{
return QRect(30, 0, width() - 30 * 2, height());
}
virtual void mousePressEvent(QMouseEvent* event) override
{
if (addButtonRect().contains(event->pos()))
{
direction = Forward;
}
else if (subButtonRect().contains(event->pos()))
{
direction = Backward;
}
else
{
return;
}
timer->start();
}
virtual void mouseReleaseEvent(QMouseEvent* event) override
{
timer->stop();
timer->setInterval(500);
}
int value;
int min;
int max;
Direction direction;
QTimer* timer;
};
答案 1 :(得分:2)
此功能已在Qt中实现。
启用QPushButton
的{{3}}属性。按下按钮时,它将定期触发按钮的clicked
信号。
只需照常连接插槽即可。