Qt托盘消息通知(③托盘消息列表)
实现思路
- 创建消息窗口:使用
QWidget
或QDialog
来创建一个显示消息的窗口。 - 使用
QListWidget
:在消息窗口中使用QListWidget
来动态显示消息。 - 添加滑块:如果消息数量超过5条,使用
QScrollArea
来实现滑动功能。 - 更新消息列表:每次接收到新的消息时更新消息列表。
完整代码示例
以下是如何在之前的托盘图标基础上实现消息列表功能的完整代码:
main.cpp
#include <QApplication> #include <QSystemTrayIcon> #include <QMenu> #include <QAction> #include <QWidget> #include <QTimer> #include <QIcon> #include <QCursor> #include <QListView> #include <QAbstractListModel> #include <QVBoxLayout> #include <QScrollBar> class MessageModel : public QAbstractListModel { public: MessageModel(QObject *parent = nullptr) : QAbstractListModel(parent) {} void addMessage(const QString &message) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); messages.append(message); endInsertRows(); } int rowCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return messages.size(); } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { if (!index.isValid() || index.row() < 0 || index.row() >= messages.size()) return QVariant(); if (role == Qt::DisplayRole) { return messages.at(index.row()); } return QVariant(); } private: QStringList messages; }; class TrayApp : public QWidget { public: TrayApp() { trayIcon = new QSystemTrayIcon(QIcon(":/Image/QQ图标.png"), this); trayIcon->setToolTip("消息托盘"); // 创建菜单 QMenu *menu = new QMenu(); QAction *exitAction = menu->addAction("退出"); connect(exitAction, &QAction::triggered, qApp, &QApplication::quit); trayIcon->setContextMenu(menu); trayIcon->show(); // 消息模型 model = new MessageModel(this); view = new QListView(); view->setModel(model); view->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); // 显示滚动条 view->setFrameShape(QFrame::NoFrame); // 去掉边框 // 安装事件过滤器以监测鼠标进入和离开事件 view->installEventFilter(this); // 定时器,模拟新消息 messageTimer = new QTimer(this); connect(messageTimer, &QTimer::timeout, this, &TrayApp::simulateNewMessage); messageTimer->start(5000); // 每5秒模拟一次新消息 // 闪烁定时器 flashTimer = new QTimer(this); connect(flashTimer, &QTimer::timeout, this, &TrayApp::toggleIcon); // 定时器检测鼠标位置 mousePositionTimer = new QTimer(this); connect(mousePositionTimer, &QTimer::timeout, this, &TrayApp::checkMousePosition); mousePositionTimer->start(100); // 每100毫秒检查一次鼠标位置 } protected: bool eventFilter(QObject *obj, QEvent *event) override { if (obj == view) { if (event->type() == QEvent::Enter) { view->show(); // 鼠标进入列表时显示 } else if (event->type() == QEvent::Leave) { view->hide(); // 鼠标离开列表时隐藏 } } return QWidget::eventFilter(obj, event); } private slots: void simulateNewMessage() { QString sender = "用户" + QString::number(model->rowCount() + 1); model->addMessage(sender); // 添加新消息 trayIcon->showMessage("新消息", "您有一条新消息!", QSystemTrayIcon::Information); // 启动闪烁定时器 flashTimer->start(500); // 每500毫秒切换一次图标 } void toggleIcon() { static bool isFlashing = false; if (isFlashing) { trayIcon->setIcon(QIcon(":/Image/QQ图标.png")); // 正常图标 } else { trayIcon->setIcon(QIcon(":/Image/QQ图标-未登录.png")); // 闪烁图标 } isFlashing = !isFlashing; } void checkMousePosition() { QPoint cursorPos = QCursor::pos(); // 获取鼠标位置 QRect trayRect = trayIcon->geometry(); // 获取托盘图标的几何形状 if (trayRect.contains(cursorPos)) { // 计算列表的高度 int itemHeight = view->sizeHintForRow(0); // 获取每个列表项的高度 int height = qMin(model->rowCount() * itemHeight, 5 * itemHeight); // 最大高度为5条消息的高度 view->setFixedHeight(height); // 设置列表固定高度 view->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); // 设置窗口样式 view->move(trayRect.x(), trayRect.y() - height); // 显示在托盘上方 view->show(); } else { if (!view->underMouse()) { view->hide(); // 隐藏消息列表 } } } private: QSystemTrayIcon *trayIcon; QTimer *flashTimer; QTimer *messageTimer; QTimer *mousePositionTimer; MessageModel *model; QListView *view; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); app.setQuitOnLastWindowClosed(false); TrayApp trayApp; // 创建托盘应用实例 return app.exec(); }
代码说明
- 消息窗口:
MessageWindow
继承自QWidget
,用来显示消息。- 使用
QListWidget
来显示消息内容,并限制其高度,使其能够在超出5条后
代码效果展示
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具