-
Notifications
You must be signed in to change notification settings - Fork 7
/
mytitlebar.cpp
332 lines (288 loc) · 9.61 KB
/
mytitlebar.cpp
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#include "mytitlebar.h"
#include "mytitlebar.h"
#include <QHBoxLayout>
#include <QPainter>
#include <QFile>
#include <QMouseEvent>
#define BUTTON_HEIGHT 30 // 按钮高度;
#define BUTTON_WIDTH 30 // 按钮宽度;
#define TITLE_HEIGHT 30 // 标题栏高度;
MyTitleBar::MyTitleBar(QWidget *parent) : QWidget(parent)
, m_colorR(153)
, m_colorG(153)
, m_colorB(153)
, m_isPressed(false)
, m_buttonType(MIN_MAX_BUTTON)
, m_windowBorderWidth(0)
, m_isTransparent(false)
{
// 初始化;
initControl();
initConnections();
// 加载本地样式 MyTitle.css文件;
//loadStyleSheet("MyTitle");
}
MyTitleBar::~MyTitleBar()
{
}
// 初始化控件;
void MyTitleBar::initControl()
{
m_pIcon = new QLabel;
m_pTitleContent = new QLabel;
m_pButtonMin = new QPushButton;
m_pButtonRestore = new QPushButton;
m_pButtonMax = new QPushButton;
m_pButtonClose = new QPushButton;
m_pButtonMin->setFixedSize(QSize(BUTTON_WIDTH, BUTTON_HEIGHT));
m_pButtonRestore->setFixedSize(QSize(BUTTON_WIDTH, BUTTON_HEIGHT));
m_pButtonMax->setFixedSize(QSize(BUTTON_WIDTH, BUTTON_HEIGHT));
m_pButtonClose->setFixedSize(QSize(BUTTON_WIDTH, BUTTON_HEIGHT));
m_pTitleContent->setObjectName("TitleContent");
m_pButtonMin->setObjectName("ButtonMin");
m_pButtonRestore->setObjectName("ButtonRestore");
m_pButtonMax->setObjectName("ButtonMax");
m_pButtonClose->setObjectName("ButtonClose");
m_pButtonMin->setToolTip(QStringLiteral("最小化"));
m_pButtonRestore->setToolTip(QStringLiteral("还原"));
m_pButtonMax->setToolTip(QStringLiteral("最大化"));
m_pButtonClose->setToolTip(QStringLiteral("关闭"));
m_pButtonMax->setStyleSheet(tr("border-image: url(:/new/login/icon/max.png);"));
m_pButtonMin->setStyleSheet(tr("border-image: url(:/new/login/icon/min.png);"));
m_pButtonClose->setStyleSheet(tr("border-image: url(:/new/login/icon/close.png);"));
QHBoxLayout* mylayout = new QHBoxLayout(this);
mylayout->addWidget(m_pIcon);
mylayout->addWidget(m_pTitleContent);
mylayout->addWidget(m_pButtonMin);
mylayout->addWidget(m_pButtonRestore);
mylayout->addWidget(m_pButtonMax);
mylayout->addWidget(m_pButtonClose);
mylayout->setContentsMargins(5, 0, 0, 0);
mylayout->setSpacing(0);
m_pTitleContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
this->setFixedHeight(TITLE_HEIGHT);
this->setWindowFlags(Qt::FramelessWindowHint);
}
// 信号槽的绑定;
void MyTitleBar::initConnections()
{
connect(m_pButtonMin, SIGNAL(clicked()), this, SLOT(onButtonMinClicked()));
connect(m_pButtonRestore, SIGNAL(clicked()), this, SLOT(onButtonRestoreClicked()));
connect(m_pButtonMax, SIGNAL(clicked()), this, SLOT(onButtonMaxClicked()));
connect(m_pButtonClose, SIGNAL(clicked()), this, SLOT(onButtonCloseClicked()));
}
// 设置标题栏背景色,在paintEvent事件中进行绘制标题栏背景色;
// 在构造函数中给了默认值,可以外部设置颜色值改变标题栏背景色;
void MyTitleBar::setBackgroundColor(int r, int g, int b, bool isTransparent)
{
m_colorR = r;
m_colorG = g;
m_colorB = b;
m_isTransparent = isTransparent;
// 重新绘制(调用paintEvent事件);
update();
}
// 设置标题栏图标;
void MyTitleBar::setTitleIcon(QString filePath, QSize IconSize)
{
QPixmap titleIcon(filePath);
m_pIcon->setPixmap(titleIcon.scaled(IconSize));
}
// 设置标题内容;
void MyTitleBar::setTitleContent(QString titleContent, int titleFontSize)
{
// 设置标题字体大小;
QFont font = m_pTitleContent->font();
font.setPointSize(titleFontSize);
m_pTitleContent->setFont(font);
// 设置标题内容;
m_pTitleContent->setText(titleContent);
m_titleContent = titleContent;
}
// 设置标题栏长度;
void MyTitleBar::setTitleWidth(int width)
{
this->setFixedWidth(width);
}
// 设置标题栏上按钮类型;
// 由于不同窗口标题栏上的按钮都不一样,所以可以自定义标题栏中的按钮;
// 这里提供了四个按钮,分别为最小化、还原、最大化、关闭按钮,如果需要其他按钮可自行添加设置;
void MyTitleBar::setButtonType(ButtonType buttonType)
{
m_buttonType = buttonType;
switch (buttonType)
{
case MIN_BUTTON:
{
m_pButtonRestore->setVisible(false);
m_pButtonMax->setVisible(false);
}
break;
case MIN_MAX_BUTTON:
{
m_pButtonRestore->setVisible(false);
}
break;
case ONLY_CLOSE_BUTTON:
{
m_pButtonMin->setVisible(false);
m_pButtonRestore->setVisible(false);
m_pButtonMax->setVisible(false);
}
break;
default:
break;
}
}
// 设置标题栏中的标题是否会自动滚动,跑马灯的效果;
// 一般情况下标题栏中的标题内容是不滚动的,但是既然自定义就看自己需要嘛,想怎么设计就怎么搞O(∩_∩)O!
void MyTitleBar::setTitleRoll()
{
connect(&m_titleRollTimer, SIGNAL(timeout()), this, SLOT(onRollTitle()));
m_titleRollTimer.start(200);
}
// 设置窗口边框宽度;
void MyTitleBar::setWindowBorderWidth(int borderWidth)
{
m_windowBorderWidth = borderWidth;
}
// 保存窗口最大化前窗口的位置以及大小;
void MyTitleBar::saveRestoreInfo(const QPoint point, const QSize size)
{
m_restorePos = point;
m_restoreSize = size;
}
// 获取窗口最大化前窗口的位置以及大小;
void MyTitleBar::getRestoreInfo(QPoint& point, QSize& size)
{
point = m_restorePos;
size = m_restoreSize;
}
// 绘制标题栏背景色;
void MyTitleBar::paintEvent(QPaintEvent *event)
{
// 是否设置标题透明;
if (!m_isTransparent)
{
//设置背景色;
QPainter painter(this);
QPainterPath pathBack;
pathBack.setFillRule(Qt::WindingFill);
pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 3, 3);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.fillPath(pathBack, QBrush(QColor(m_colorR, m_colorG, m_colorB)));
}
// 当窗口最大化或者还原后,窗口长度变了,标题栏的长度应当一起改变;
// 这里减去m_windowBorderWidth ,是因为窗口可能设置了不同宽度的边框;
// 如果窗口有边框则需要设置m_windowBorderWidth的值,否则m_windowBorderWidth默认为0;
if (this->width() != (this->parentWidget()->width() - m_windowBorderWidth))
{
this->setFixedWidth(this->parentWidget()->width() - m_windowBorderWidth);
}
QWidget::paintEvent(event);
}
// 双击响应事件,主要是实现双击标题栏进行最大化和最小化操作;
void MyTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
// 只有存在最大化、还原按钮时双击才有效;
#if 0
if (m_buttonType == MIN_MAX_BUTTON)
{
// 通过最大化按钮的状态判断当前窗口是处于最大化还是原始大小状态;
// 或者通过单独设置变量来表示当前窗口状态;
if (m_pButtonMax->isVisible())
{
onButtonMaxClicked();
}
else
{
onButtonRestoreClicked();
}
}
#endif
return QWidget::mouseDoubleClickEvent(event);
}
// 以下通过mousePressEvent、mouseMoveEvent、mouseReleaseEvent三个事件实现了鼠标拖动标题栏移动窗口的效果;
void MyTitleBar::mousePressEvent(QMouseEvent *event)
{
if (m_buttonType == MIN_MAX_BUTTON)
{
// 在窗口最大化时禁止拖动窗口;
if (m_pButtonMax->isVisible())
{
m_isPressed = true;
m_startMovePos = event->globalPos();
}
}
else
{
m_isPressed = true;
m_startMovePos = event->globalPos();
}
return QWidget::mousePressEvent(event);
}
void MyTitleBar::mouseMoveEvent(QMouseEvent *event)
{
if (m_isPressed)
{
QPoint movePoint = event->globalPos() - m_startMovePos;
QPoint widgetPos = this->parentWidget()->pos();
m_startMovePos = event->globalPos();
this->parentWidget()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());
}
return QWidget::mouseMoveEvent(event);
}
void MyTitleBar::mouseReleaseEvent(QMouseEvent *event)
{
m_isPressed = false;
return QWidget::mouseReleaseEvent(event);
}
#if 0
// 加载本地样式文件;
// 可以将样式直接写在文件中,程序运行时直接加载进来;
void MyTitleBar::loadStyleSheet(const QString &sheetName)
{
QFile file(":/Resources/" + sheetName + ".css");
file.open(QFile::ReadOnly);
if (file.isOpen())
{
QString styleSheet = this->styleSheet();
styleSheet += QLatin1String(file.readAll());
this->setStyleSheet(styleSheet);
}
}
#endif
// 以下为按钮操作响应的槽;
void MyTitleBar::onButtonMinClicked()
{
emit signalButtonMinClicked();
}
void MyTitleBar::onButtonRestoreClicked()
{
m_pButtonRestore->setVisible(false);
m_pButtonMax->setVisible(true);
emit signalButtonRestoreClicked();
}
void MyTitleBar::onButtonMaxClicked()
{
#if 0
m_pButtonMax->setVisible(false);
m_pButtonRestore->setVisible(true);
emit signalButtonMaxClicked();
#endif
}
void MyTitleBar::onButtonCloseClicked()
{
emit signalButtonCloseClicked();
}
// 该方法主要是让标题栏中的标题显示为滚动的效果;
void MyTitleBar::onRollTitle()
{
static int nPos = 0;
QString titleContent = m_titleContent;
// 当截取的位置比字符串长时,从头开始;
if (nPos > titleContent.length())
nPos = 0;
m_pTitleContent->setText(titleContent.mid(nPos));
nPos++;
}