-
Notifications
You must be signed in to change notification settings - Fork 58
Expand file tree
/
Copy pathdlineeditex.cpp
More file actions
185 lines (164 loc) · 5.72 KB
/
dlineeditex.cpp
File metadata and controls
185 lines (164 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "dlineeditex.h"
#include <DFontSizeManager>
#include <QGuiApplication>
#include <QPainter>
#include <QPropertyAnimation>
#include <QVariantAnimation>
#include <QKeyEvent>
LoadSlider::LoadSlider(QWidget *parent)
: QWidget(parent)
, m_loadSliderColor(Qt::gray)
{
}
void LoadSlider::setLoadSliderColor(const QColor &color)
{
m_loadSliderColor = color;
}
void LoadSlider::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QLinearGradient grad(0, height() / 2, width(), height() / 2);
grad.setColorAt(0.0, Qt::transparent);
grad.setColorAt(1.0, m_loadSliderColor);
painter.fillRect(0, 0, width(), height() - 1, grad);
QWidget::paintEvent(event);
}
DLineEditEx::DLineEditEx(QWidget *parent)
: DLineEdit(parent)
, m_loadSlider(new LoadSlider(this))
, m_animation(new QPropertyAnimation(m_loadSlider, "pos", m_loadSlider))
, m_enableTableKeyEvent(false)
{
setObjectName(QStringLiteral("DLineEditEx"));
setAccessibleName(QStringLiteral("DLineEditEx"));
initAnimation();
#if 0 // FIXME:不生效,改为在eventFilter过滤InputMethodQuery事件
// 在锁屏或登录界面,输入类型的控件不要唤出输入法
setAttribute(Qt::WA_InputMethodEnabled, false);
this->lineEdit()->setAttribute(Qt::WA_InputMethodEnabled, false);
#endif
this->lineEdit()->installEventFilter(this);
this->installEventFilter(this);
connect(qGuiApp, &QGuiApplication::fontChanged, this, &DLineEditEx::setPlaceholderTextFont);
}
/**
* @brief 初始化动画
*/
void DLineEditEx::initAnimation()
{
m_loadSlider->setGeometry(0, -40, 40, height());
m_loadSlider->setLoadSliderColor(QColor(255, 255, 255, 90));
m_loadSlider->setAccessibleName("LoadSlider");
m_animation->setDuration(1000);
m_animation->setLoopCount(-1);
m_animation->setEasingCurve(QEasingCurve::Linear);
m_animation->targetObject();
}
/**
* @brief 设置字体
* @param font
*/
void DLineEditEx::setPlaceholderTextFont(const QFont &font)
{
const QString &text = lineEdit()->placeholderText();
QFont fontTmp = font;
while (QFontMetrics(fontTmp).boundingRect(text).width() > width()) {
// 防止陷入死循环,setPointSize当参数为负数的时候设置不生效
// TODO: font()获取问题,需要继续调查下为啥font为啥会出问题,但是这里也需要增加跳出死循环的条件
qDebug() << "Password line edit placeholder text width : " << QFontMetrics(fontTmp).boundingRect(text).width() << " line edit width : " << width();
if (fontTmp.pointSize() <= 1) {
qWarning() << "Password line edit font size" << font.pointSize() << fontTmp.pointSize();
return;
}
fontTmp.setPointSize(fontTmp.pointSize() - 1);
}
setFont(fontTmp);
}
/**
* @brief 显示动画
*/
void DLineEditEx::startAnimation()
{
if (m_animation->state() == QAbstractAnimation::Running) {
return;
}
m_loadSlider->show();
m_loadSlider->resize(40, height());
// 动画块距离右侧的距离10px结束
int endX = (width() - m_loadSlider->width() - 10) > 0 ? width() - m_loadSlider->width() - 10 : width();
m_animation->setStartValue(QPoint(0, 0));
m_animation->setEndValue(QPoint(endX, 0));
m_animation->start();
}
/**
* @brief 隐藏动画
*/
void DLineEditEx::stopAnimation()
{
if (m_animation->state() == QAbstractAnimation::Stopped) {
return;
}
m_loadSlider->hide();
m_animation->stop();
}
void DLineEditEx::setEnableTableKeyEvent(bool enable)
{
if (m_enableTableKeyEvent == enable)
return;
m_enableTableKeyEvent = enable;
}
/**
* @brief 重写 QLineEdit paintEvent 函数,实现当文本设置居中后,holderText 仍然显示的需求
*
* @param event
*/
void DLineEditEx::paintEvent(QPaintEvent *event)
{
setPlaceholderTextFont(font());
if (lineEdit()->hasFocus() && lineEdit()->alignment() == Qt::AlignCenter
&& !lineEdit()->placeholderText().isEmpty() && lineEdit()->text().isEmpty()) {
QPainter pa(this);
QPalette pal = palette();
QColor col = pal.text().color();
col.setAlpha(128);
QPen oldpen = pa.pen();
pa.setPen(col);
QTextOption option;
option.setAlignment(Qt::AlignCenter);
option.setWrapMode(QTextOption::NoWrap);
// 使用 elidedText 确保文本过长时在右侧显示省略号,而不是换行
QFontMetrics fm(pa.font());
const QString &placeholderText = lineEdit()->placeholderText();
QString elidedText = fm.elidedText(placeholderText, Qt::ElideRight, rect().width());
pa.drawText(rect(), Qt::AlignCenter | Qt::TextSingleLine, elidedText);
// 当文本被省略时,设置 tooltip 显示完整文本
if (elidedText != placeholderText) {
setToolTip(placeholderText);
} else {
setToolTip(QString());
}
}
QWidget::paintEvent(event);
}
bool DLineEditEx::eventFilter(QObject *watched, QEvent *event)
{
// 禁止输入法
if ((watched == this || watched == this->lineEdit())
&& event->type() == QEvent::InputMethodQuery) {
return true;
} else if ((watched == this || watched == this->lineEdit())
&& event->type() == QEvent::KeyPress
&& m_enableTableKeyEvent) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Tab
&& keyEvent->modifiers() == Qt::NoModifier
&& !this->text().isEmpty()) {
emit this->returnPressed();
return true;
}
}
return DLineEdit::eventFilter(watched, event);
}