滚动显示
需求:超出当前控件长度的时候,文字可以滚动显示。
分解一下:
- 如何判断当前显示的内容是否超过了控件的长度?
通过 QFontMetrics 类,可获取当前字体文本的宽度。QFont ft = font(); QFontMetrics fm(font); int text_width = fm->width(text());
- 如何实现滚动?
通过定时器来将文本的内容滚动起来。我使用的是QObject自带的timerEvent来实现;void QLabelPro::timerEvent(QTimerEvent *event) { if(event->timerId() == firstTimeId && isVisible()) { timerID = startTimer(100); } if(event->timerId() == timerID && isVisible()) { if(firstTimeId >= 0) { killTimer(firstTimeId); firstTimeId = -1; } left += 5; QFont ft = font(); QFontMetrics fm(ft); int txtWidth = fm.width(text()); int spaceWidth = fm.width(strSpace); if((txtWidth + spaceWidth) < left) left = 0; repaint(); } QLabel::timerEvent(event); }
发送点击信号
点击这个动作可以分解为“按下”和“抬起”,所以实现思路是通过重写mousePressEvent和mouseReleaseEvent的方式。
void QLabelPro::mousePressEvent(QMouseEvent *ev)
{
perss_flag = true;
QLabel::mousePressEvent(ev);
}
void QLabelPro::mouseReleaseEvent(QMouseEvent *ev)
{
if(perss_flag) {
perss_flag = false;
emit Clicked();
}
QLabel::mouseReleaseEvent(ev);
}
其中的perss_flag变量是用来保证”按下“与“抬起”是按照顺序在该控件中发生的。
源码
qlabelpro.cpp
#include "qlabelpro.h"
#include <QTimerEvent>
#include <QMouseEvent>
#include <QPainter>
QLabelPro::QLabelPro(QWidget *parent) : QLabel(parent)
{
strSpace = " ";
firstTimeId = -1;
timerID = -1;
perss_flag = false;
}
void QLabelPro::updateLabelRollingState()
{
QFont ft = font();
QFontMetrics fm(ft);
int nW = fm.width(text());
left = 0;
if(timerID >= 0) {
killTimer(timerID);
timerID = -1;
}
if(firstTimeId >= 0) {
killTimer(firstTimeId);
firstTimeId = -1;
}
if(nW > width()) {
firstTimeId = startTimer(3000);
} else {
if(timerID >= 0) {
killTimer(timerID);
timerID = -1;
}
if(firstTimeId >= 0) {
killTimer(firstTimeId);
firstTimeId = -1;
}
}
}
void QLabelPro::timerEvent(QTimerEvent *event)
{
if(event->timerId() == firstTimeId && isVisible()) {
timerID = startTimer(100);
}
if(event->timerId() == timerID && isVisible()) {
if(firstTimeId >= 0) {
killTimer(firstTimeId);
firstTimeId = -1;
}
left += 5;
QFont ft = font();
QFontMetrics fm(ft);
int txtWidth = fm.width(text());
int spaceWidth = fm.width(strSpace);
if((txtWidth + spaceWidth) < left)
left = 0;
repaint();
}
QLabel::timerEvent(event);
}
void QLabelPro::paintEvent(QPaintEvent *e)
{
QPainter p(this);
QRect rc = rect();
rc.setHeight(rc.height()-2);
rc.setWidth(rc.width()-2);
QFont ft = font();
p.setFont(ft);
rc.setLeft(rc.left() - left);
QString strText = text();
if(timerID >= 0) {
strText += strSpace + text();
}
p.drawText(rc, Qt::AlignVCenter, strText);
}
void QLabelPro::resizeEvent(QResizeEvent *event)
{
QLabel::resizeEvent(event);
updateLabelRollingState();
}
void QLabelPro::mousePressEvent(QMouseEvent *ev)
{
perss_flag = true;
QLabel::mousePressEvent(ev);
}
void QLabelPro::mouseReleaseEvent(QMouseEvent *ev)
{
if(perss_flag) {
perss_flag = false;
emit Clicked();
}
QLabel::mouseReleaseEvent(ev);
}
void QLabelPro::setText(const QString & text)
{
QLabel::setText(text);
updateLabelRollingState();
}
qlabelpro.h
#ifndef QLABELPRO_H
#define QLABELPRO_H
#include <QLabel>
class QLabelPro : public QLabel
{
Q_OBJECT
public:
explicit QLabelPro(QWidget *parent = nullptr);
void setText(const QString & text);
private :
int timerID;
int firstTimeId;
int left;
QString strSpace;
bool perss_flag;
void updateLabelRollingState();
void timerEvent(QTimerEvent* event);
void paintEvent(QPaintEvent* e);
void resizeEvent(QResizeEvent *event);
void mousePressEvent(QMouseEvent *ev);
void mouseReleaseEvent(QMouseEvent *ev);
signals:
void Clicked();
public slots:
};
#endif // QLABELPRO_H
写在后面
要想进步还是需要多分享多总结。
如有问题欢迎留言指正【抱拳】。