介绍
最近做了一款键鼠自动化,想第一次安装打开后搞一个引导界面,找了好多资料没啥参考,偶然发现qt有引导界面如下图。
Qt整挺好,但是未找到源码,真的不想手撸,无奈实在找不到,下图是仿照qt实现。
废话少说
直接上代码
#ifndef TOURGUIDE_H
#define TOURGUIDE_H
#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QPalette>
#include <QBrush>
enum WSAD_POS {
TOP_POS,
DOWN_PPOS,
LEFT_POS,
RIGHT_POS
};
class TourGuide : public QWidget
{
Q_OBJECT
public:
explicit TourGuide(QWidget* w, QWidget *parent = 0);
void onAddWidget(QWidget* w, QString title, QStringList contentList, int pos);
signals:
public slots:
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
//绘制箭头 WSAD绘制方向
void drawArrows(QPainter& painter, QPoint pos, QRect rect, WSAD_POS WSAD);
private:
QList<QWidget*> m_ListWidget;
QList<QString> m_ListWidgetStr;
QList<QStringList> m_ListWidgetStrList;
QList<WSAD_POS> m_ListWidgetPos;
int m_index = 0;
QWidget* m_MainWindows;
QLine targetLine;
};
#endif // TOURGUIDE_H
#include "tourguide.h"
#include <QDebug>
TourGuide::TourGuide(QWidget *w, QWidget *parent) : QWidget(parent)
{
m_MainWindows = w;
}
void TourGuide::onAddWidget(QWidget *w, QString title, QStringList contentList, int pos)
{
m_ListWidget << w;
m_ListWidgetStr << title;
m_ListWidgetStrList << contentList;
m_ListWidgetPos << WSAD_POS(pos);
}
void TourGuide::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
if (m_index < 0 || m_index >= m_ListWidget.size())
return;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QWidget *currentWidget = m_ListWidget[m_index];
if (!currentWidget)
return;
// 获取QWidget在主窗体的位置
QPoint guidePos = currentWidget->mapTo(m_MainWindows, QPoint(0, 0));
QRect rect(guidePos.x(), guidePos.y(), currentWidget->width(), currentWidget->height());
//循环如果包含该ui就不绘制
for (int i = 0 ; i < this->width(); ++i) {
for (int j = 0 ; j < this->height(); ++j) {
if (!rect.contains(QPoint(i, j))) {
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 0, 100));
painter.drawRect(i, j, 1, 1);
}
}
}
painter.setBrush(QColor(0, 0, 0, 0));
QPen pen(Qt::green);
//圈出来
pen.setWidth(1);
painter.setPen(pen);
painter.drawRect(rect);
drawArrows(painter, guidePos, currentWidget->rect(), m_ListWidgetPos.at(m_index));
// 绘制矩形框和箭头
// 绘制文字
painter.setPen(Qt::white); // 设置文字颜色为白色
QFont font = painter.font(); // 获取当前字体设置
font.setPointSize(18); // 设置字体大小
font.setBold(true); // 设置为粗体
painter.setFont(font); // 应用设置后的字体
// 获取文本的宽度和高度
QRectF textRect = painter.boundingRect(QRectF(), Qt::AlignCenter, m_ListWidgetStr.at(m_index));
// 计算文字应该绘制的位置,使其居中在窗口中央
qreal x = (this->width() - textRect.width()) / 2;
qreal y = (this->height() - textRect.height()) / 2;
// 绘制标题文字
painter.drawText(QPointF(x, y), m_ListWidgetStr.at(m_index));
QStringList list = m_ListWidgetStrList.at(m_index);
// 绘制子文字
for (int i = 0 ; i < list.size(); ++i) {
textRect = painter.boundingRect(QRectF(), Qt::AlignCenter, list.at(i));
x = (this->width() - textRect.width()) / 2;
y = (this->height() - textRect.height()) / 2 + ((i+1) * 40);
font.setPointSize(12);
font.setBold(false);
painter.setFont(font); // 应用设置后的字体
// 绘制标题文字
painter.drawText(QPointF(x, y), list.at(i));
}
}
void TourGuide::mousePressEvent(QMouseEvent *event)
{
if (event->type() == QMouseEvent::MouseButtonPress) {
this->update();
qDebug() << m_index;
if (m_index < m_ListWidget.size()) {
m_index++;
}
else {
this->close();
}
}
}
void TourGuide::drawArrows(QPainter &painter, QPoint pos, QRect rect, WSAD_POS WSAD)
{
QPoint f1Start;
QPoint f1Stop;
QPoint f2Start;
QPoint f2Stop;
QPoint f3Start;
QPoint f3Stop;
if (WSAD == TOP_POS) {
// 绘制箭头
f1Start = QPoint(pos.x() + (rect.width() / 2), pos.y() - 5);
f1Stop = QPoint(pos.x() + (rect.width() / 2) - 6, pos.y() - 12);
//绘制两边的线
f2Start = QPoint(pos.x() + (rect.width() / 2), pos.y() - 5);
f2Stop = QPoint(pos.x() + (rect.width() / 2) + 6, pos.y() - 12);
//绘制中间的线
f3Start = QPoint(pos.x() + (rect.width() / 2), pos.y() - 5);
f3Stop = QPoint(pos.x() + (rect.width() / 2), pos.y() - 20);
}
else if (WSAD == DOWN_PPOS) {
// 绘制箭头
f1Start = QPoint(pos.x() + (rect.width() / 2), pos.y() + rect.height() + 5);
f1Stop = QPoint(pos.x() + (rect.width() / 2) - 6, pos.y() + rect.height() + 12);
//绘制两边的线
f2Start = QPoint(pos.x() + (rect.width() / 2), pos.y() + rect.height() + 5);
f2Stop = QPoint(pos.x() + (rect.width() / 2) + 6, pos.y() + rect.height() + 12);
//绘制中间的线
f3Start = QPoint(pos.x() + (rect.width() / 2), pos.y() + rect.height() + 5);
f3Stop = QPoint(pos.x() + (rect.width() / 2), pos.y() + rect.height() + 20);
}
else if (WSAD == LEFT_POS) {
// 绘制箭头
f1Start = QPoint(pos.x() - 5, pos.y() + (rect.height() / 2));
f1Stop = QPoint(pos.x() - 12, pos.y() + 5);
//绘制两边的线
f2Start = QPoint(pos.x() - 5, pos.y() + (rect.height() / 2));
f2Stop = QPoint(pos.x() - 12, pos.y() + (rect.height() / 2) + 6);
//绘制中间的线
f3Start = QPoint(pos.x() - 5, pos.y() + rect.height() / 2);
f3Stop = QPoint(pos.x() - 20, pos.y() + rect.height() / 2);
}
else if (WSAD == RIGHT_POS) {
// 绘制箭头
f1Start = QPoint(pos.x() + rect.width() + 5, pos.y() + (rect.height() / 2));
f1Stop = QPoint(pos.x() + rect.width() + 12, pos.y() + 5);
//绘制两边的线
f2Start = QPoint(pos.x() + rect.width() + 5, pos.y() + (rect.height() / 2));
f2Stop = QPoint(pos.x() + rect.width() + 12, pos.y() + (rect.height() / 2) + 6);
//绘制中间的线
f3Start = QPoint(pos.x() + rect.width() + 5, pos.y() + rect.height() / 2);
f3Stop = QPoint(pos.x() + rect.width() + 20, pos.y() + rect.height() / 2);
}
QPen pen(Qt::green);
pen.setWidth(2);
painter.setPen(pen);
painter.drawLine(f1Start, f1Stop);
painter.drawLine(f2Start, f2Stop);
painter.drawLine(f3Start, f3Stop);
}
调用方式
m_T = new TourGuide(this, this);
m_T->onAddWidget(ui->pushButton, "这是第1个按钮", QStringList() << "他是第1个", 0);
m_T->onAddWidget(ui->pushButton_2, "这是第2个按钮", QStringList() << "他是第2个", 1);
m_T->onAddWidget(ui->pushButton_3, "这是第3个按钮", QStringList() << "他是第3个", 2);
m_T->onAddWidget(ui->pushButton_4, "这是第4个按钮", QStringList() << "他是第4个", 3);
m_T->setFixedSize(this->size());