Qt QWidget实现自己的桌面萌宠源码分享
一、效果展示
二、源码分享
1、 petWidget.h
#ifndef PETWIDGET_H
#define PETWIDGET_H
#include <QWidget>
#include <QMovie>
#include <QMouseEvent>
#include <QMenu>
#include "petDialogWidget.h"
namespace Ui {
class PetWidget;
}
class PetWidget : public QWidget
{
Q_OBJECT
public:
explicit PetWidget(QWidget *parent = nullptr);
~PetWidget();
void showDialog(QString content,uint16_t timerout);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
void contextMenuEvent(QContextMenuEvent *event) override;
private:
void controlInit();
private:
Ui::PetWidget *ui;
PetDialogWidget *petDialog = nullptr;
QMovie *movie = nullptr;
QPoint pressedPoint;
bool leftBtnPressed = false;
};
#endif // PETWIDGET_H
2、petWidget.cpp
#include "petWidget.h"
#include "ui_petWidget.h"
PetWidget::PetWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::PetWidget)
{
ui->setupUi(this);
this->controlInit();
}
PetWidget::~PetWidget()
{
this->petDialog->close();
delete this->petDialog;
delete ui;
}
void PetWidget::controlInit()
{
this->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Tool);
this->setAttribute(Qt::WA_TranslucentBackground); // 设置窗口背景透明
this->petDialog = new PetDialogWidget();
this->movie = new QMovie(":/image/image/pet.gif"); // 加载资源文件中的GIF动画
this->movie->setScaledSize(QSize(100,150));
this->ui->label->setMovie(this->movie);
connect(this->movie,&QMovie::frameChanged,this,
[=](int frameNumber)
{
if (frameNumber == movie->frameCount() - 1)
{
this->movie->stop();
}
});
this->movie->start();
this->installEventFilter(this);
this->ui->label->installEventFilter(this);
}
void PetWidget::showDialog(QString content, uint16_t timerout)
{
int x = this->x() + (this->width() - this->petDialog->width())/2;
int y = this->y() - this->petDialog->height();
this->petDialog->showContent(x,y,content,timerout);
}
bool PetWidget::eventFilter(QObject *obj, QEvent *event)
{
if(obj == this)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* e = static_cast<QMouseEvent *>(event);
if(e->button() == Qt::LeftButton)
{
this->pressedPoint = e->globalPos() - pos();
this->leftBtnPressed = true;
this->ui->label->setCursor(QCursor(Qt::ClosedHandCursor));
}
}
else if(event->type() == QEvent::MouseMove)
{
QMouseEvent* e = static_cast<QMouseEvent *>(event);
if(this->leftBtnPressed)
{
this->move(e->globalPos() - this->pressedPoint);
int x = this->x() + (this->width() - this->petDialog->width())/2;
int y = this->y() - this->petDialog->height();
this->petDialog->move(x,y);
}
}
else if(event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* e = static_cast<QMouseEvent *>(event);
if(e->button() == Qt::LeftButton)
{
this->leftBtnPressed = false;
this->ui->label->setCursor(QCursor(Qt::OpenHandCursor));
}
}
}
else if(obj == this->ui->label)
{
if(event->type() == QEvent::Enter)
{
this->movie->start();
}
}
return false;
}
void PetWidget::contextMenuEvent(QContextMenuEvent *event)
{
QMenu menu(this);
QString qss = R"(
QMenu {
background-color: #FDA330;
border: 1px solid white;
font-size: 13px;
border-radius:10px;
background-clip: padding-box;
}
QMenu::item {
padding: 8px 24px;
border: 1px solid white;
}
QMenu::item:selected {
background: #00ffff;
color: #0066cc;
}
)";
menu.setStyleSheet(qss);
menu.setWindowFlag(Qt::FramelessWindowHint);
menu.setAttribute(Qt::WA_TranslucentBackground);
//在windows下,自带的阴影效果仍然是直角,还需设置去除阴影效果
menu.setWindowFlag(Qt::NoDropShadowWindowHint);
QAction *action1 = menu.addAction("菜单项1");
QAction *action2 = menu.addAction("菜单项2");
QAction *action3 = menu.addAction("菜单项3");
QAction *action4 = menu.addAction("菜单项4");
QAction *action5 = menu.addAction("菜单项5");
QAction *action6 = menu.addAction("菜单项6");
// menu.addAction(action1);
// menu.addAction(action2);
menu.exec(event->globalPos());
}
3、petDialogWidget.h
#ifndef PETDIALOGWIDGET_H
#define PETDIALOGWIDGET_H
#include <QWidget>
#include <QTimer>
#include <QFontDatabase>
namespace Ui {
class PetDialogWidget;
}
class PetDialogWidget : public QWidget
{
Q_OBJECT
public:
explicit PetDialogWidget(QWidget *parent = nullptr);
~PetDialogWidget();
void showContent(int x,int y,QString content,uint16_t timerout);
private:
void controlInit();
private:
Ui::PetDialogWidget *ui;
QTimer *timerClose;
};
#endif // PETDIALOGWIDGET_H
4、petDialogWidget.cpp
#include "petDialogWidget.h"
#include "ui_petDialogWidget.h"
PetDialogWidget::PetDialogWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::PetDialogWidget)
{
ui->setupUi(this);
this->controlInit();
}
PetDialogWidget::~PetDialogWidget()
{
delete ui;
}
void PetDialogWidget::controlInit()
{
this->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Tool);
this->setAttribute(Qt::WA_TranslucentBackground); // 设置窗口背景透明
this->timerClose = new QTimer(this);
connect(this->timerClose,&QTimer::timeout,this,
[=]()
{
this->close();
this->timerClose->stop();
});
// int fontId = QFontDatabase::addApplicationFont(":/font/font/XiaoXiong.ttf");
// QString fontFamily = QFontDatabase::applicationFontFamilies(fontId).at(0);
// QFont font = QFont(fontFamily,10);
// font.setBold(true);
// this->ui->label->setFont(font);
}
void PetDialogWidget::showContent(int x,int y,QString content, uint16_t timerout)
{
this->ui->label->setText(content);
this->timerClose->setInterval(timerout);
this->timerClose->start();
this->move(x,y);
this->show();
}
三、资源分享
文章前面下载完整资源!
四、实现原理
通知QLable播放gif图片来实现。
QLabel是Qt框架中的一个类,用于显示文本或图像等内容的标签控件。在Qt中,QLabel被广泛用于显示静态文本、图标和图片,并且可以与其他Qt控件一起使用,以及支持一些基本的交互功能。
以下是QLabel类的一些常见特性和用法:
-
显示文本:使用setText()方法设置QLabel显示的文本内容。可以通过setFont()方法设置文本的字体、颜色等属性。
-
显示图像:可以使用setPixmap()方法设置QLabel显示的图像。也可以使用setScaledContents()方法进行图像的缩放显示。
-
文本对齐:可以使用setAlignment()方法设置文本在QLabel中的对齐方式,包括水平对齐和垂直对齐。
-
超链接:可以通过setOpenExternalLinks()方法使文本显示为超链接形式,并在用户点击时打开外部链接。
-
提示信息:可以使用setToolTip()方法设置鼠标悬停在QLabel上时显示的提示信息。
-
交互功能:QLabel可以接受鼠标事件、键盘事件等用户操作,可以通过重写相关事件处理函数来实现用户交互。
-
自动换行:可以通过setWordWrap()方法设置文本是否自动换行显示。
-
背景色:可以使用setBackgroundRole()方法设置QLabel的背景颜色。
总的来说,QLabel是一个简单而灵活的显示控件,可以通过多种方法来设置显示内容和样式,适用于各种Qt应用程序中用于展示信息的场景。
五、资源文件下载
在文章头部。
觉得有用麻烦点个赞呗!