0%

desktop_pet_cat

learned

  • 重载QPaintEvent::paintEvent, 使之能够加载图片
  • snprintf基于printf处理字符串,QString中.arg()可以模拟,注意参数是%num;
  • connect调用的函数必须加&
  • Qpixmap::scale()用于调整大小
  • Widget::update直接更新窗口
  • 透明窗口、透明背景、与移动
1
2
3
this->setWindowFlag(Qt::FramelessWindowHint);     // 去除窗口边框
this->setAttribute(Qt::WA_TranslucentBackground); // 背景透明
this->installEventFilter(new DragFilter);
  • 最小化系统图标的使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
QSystemTrayIcon sysTray(QIcon(":/pic/image/icon.png"),&w);
QMenu menu;
auto showAct=new QAction("show",&sysTray);
auto exitAct=new QAction("exit",&sysTray);
QObject::connect(showAct,&QAction::triggered,&w,[&](){
w.setVisible(true);
});
QObject::connect(exitAct,&QAction::triggered,&a,[&](){
QApplication::quit();
});
menu.addAction(showAct);
menu.addAction(exitAct);

sysTray.setContextMenu(&menu);

sysTray.show();
  • widget::setVisible暂时关闭窗口
  • QUrl更安全的跨平台链接
  • Q_ENUM_NS(RoleAct)//注册枚举

new_learn

拖动窗口的内置函数实现

1
2
3
4
5
if (w->windowHandle())
{
w->windowHandle()->startSystemMove();
return true;
}

code

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
#include "widget.h"
#include <QPixmap>
#include <QDebug>
#include <Qcursor>
#include <QMetaEnum>
Widget::Widget(QWidget *parent)
: QWidget(parent),
timer(new QTimer(this)),//自动析构
menu(new QMenu(this))
{
this->setWindowFlag(Qt::FramelessWindowHint);//去除窗口边框
this->setAttribute(Qt::WA_TranslucentBackground);//背景透明
this->installEventFilter(new DragFilter);

connect(timer,&QTimer::timeout,this,[this](){
static int index=0;//记录显示动作的图片索引
auto paths=this->action_map.value(this->cur_role_act);
this->cur_role_pix=paths[index++%paths.size()];
//paintEvent()会递归调用
this->update();

});
loadRoleActRes();

showActAnimation(RoleAct::SayHello);
initMennu();
}

Widget::~Widget() {}

void Widget::showActAnimation(RoleAct k)
{
timer->stop();
this->cur_role_act=k;
timer->start(500);

}

void Widget::onMenuTriggered(QAction *action)
{
QMetaEnum me=QMetaEnum::fromType<RoleAct>();
bool ok;
int k=me.keyToValue(action->text().toStdString().c_str(),&ok);
if(!ok)return;
showActAnimation(static_cast<RoleAct>(k));
}

void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPixmap pix;

// qDebug()<<"pix path:"<<this->cur_role_pix.toLocalFile();
pix.load(this->cur_role_pix.toLocalFile());
int targetWidth = 200; // 你想要的宽
int targetHeight = 150; // 你想要的高
pix = pix.scaled(targetWidth, targetHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
painter.drawPixmap(0,0,pix);

}

void Widget::contextMenuEvent(QContextMenuEvent *event)
{
this->menu->popup(QCursor::pos());
}

void Widget::loadRoleActRes()
{
auto addRes=[this](RoleAct k,QString path,int count)
{
QList<QUrl>paths;
char buf[260];//path最长255
for(int i=0;i<count;++i)
{
memset(buf,0,sizeof(buf));
sprintf_s(buf,path.toStdString().c_str(),i);
paths.append(QUrl::fromLocalFile(buf));
}
action_map.insert(k,paths);
// qDebug()<<paths[1];

};
addRes(RoleAct::SayHello,":/pic/image/sayHello/sayHello%d.png",4);
addRes(RoleAct::Sleep,":/%d.png",32);
addRes(RoleAct::Swing,":/%d.png",11);


}

void Widget::initMennu()
{
menu->addAction("SayHello");
menu->addAction("Sleep");
menu->addAction("Swing");

QAction* act=new QAction("Hide");
connect(act,&QAction::triggered,this,[this](){
this->setVisible(false);
});

menu->addAction(act);
connect(this->menu,&QMenu::triggered,this,Widget::onMenuTriggered);
}

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
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QEvent>
#include <QMouseEvent>
#include <QContextMenuEvent>
#include <QMenu>

#include<QMap>
#include<QList>
#include<QUrl>
#include<QTimer>

namespace Act{
Q_NAMESPACE
enum RoleAct{
SayHello,
Swing,
Sleep,
};
Q_ENUM_NS(RoleAct)//注册枚举
}

using namespace Act;
class Widget : public QWidget
{
Q_OBJECT

public:
Widget(QWidget *parent = nullptr);
~Widget();

public:
void showActAnimation(RoleAct k);

public slots:
void onMenuTriggered(QAction *action);


protected:
void paintEvent(QPaintEvent *event)override;
void contextMenuEvent(QContextMenuEvent*event)override;

private:
void loadRoleActRes();
void initMennu();

private:
QMap<RoleAct,QList<QUrl>>action_map;
QTimer* timer;
RoleAct cur_role_act;
QUrl cur_role_pix;
QMenu* menu;
};

class DragFilter:public QObject{
public:
bool eventFilter(QObject*obj,QEvent*event)
{
auto w=dynamic_cast<QWidget*>(obj);
if(!w)
return false;
if(event->type()==QEvent::MouseButtonPress)
{
auto e =dynamic_cast<QMouseEvent*>(event);
if(e)
{
pos=e->pos();
}
}
else if(event->type()==QEvent::MouseMove)
{
auto e =dynamic_cast<QMouseEvent*>(event);
if(e)
{
if(e->buttons()&Qt::MouseButton::LeftButton)
{
w->move(e->globalPosition().toPoint()-pos);
}
}
}
return QObject::eventFilter(obj,event);

}
private:
QPoint pos;
};


#endif // WIDGET_H

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
#include "widget.h"

#include <QApplication>
#include <QSystemTrayIcon>//系统菜单托盘

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;

QSystemTrayIcon sysTray(QIcon(":/pic/image/icon.png"),&w);
QMenu menu;
auto showAct=new QAction("show",&sysTray);
auto exitAct=new QAction("exit",&sysTray);
QObject::connect(showAct,&QAction::triggered,[&](){
w.setVisible(true);
});
QObject::connect(exitAct,&QAction::triggered,[&](){
QApplication::quit();
});

menu.addAction(showAct);
menu.addAction(exitAct);

sysTray.setContextMenu(&menu);

sysTray.show();

w.show();
return a.exec();
}