本系列所有文章可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873

接上文Qt5官方demo解析集34——Concentric Circles Example

光看标题大家可能觉得我们今天会聊一聊 Qt 中 multimedia 模块的相关内容,确实,该 demo 基于这个模块实现了一个音乐播放器,不过呢,我们今天更侧重于该 demo 中 winextras 模块的使用。

从名字可以猜到,该模块可以用来为我们提供一些Windows平台上额外的扩展功能,例如DWM(Desktop Window Manager) 特效,Aero Peek,Taskbar,Jump Lists,Thumbnail Toolbar等等,Qt为我们封装了相关 API 使得它们变得更加简单易用。如果大家对这些名词感到陌生,可以前往Qt 官网查看更详细的介绍:http://doc.qt.io/qt-5/qtwinextras-overview.html 。或者,我给大家举几个身边的栗子:

不知道大家有没有留意过,当我们在使用 Qt Creator 进行构建时,其任务栏图标上的进度状态?

或者当我们将鼠标左键放在QQ音乐任务栏图标上时,出现的上一曲、暂停、下一曲这些预览窗口按钮:

亦或是,右键点击QQ音乐出现的最近收听列表:

等等之类,我就不一一列举了,站在GUI的角度来说,这些东西绝不是可有可无的

细节决定成败,用户总是能够在一些小的细节上收获惊喜和感动。

那么,看看我们如何在 Qt 中使用这些贴心的小玩意儿。

记得在pro文件中添加

  1. QT += winextras

然后看看main.cpp,这里面有个实用的关联文件格式的helper函数:

  1. #include "musicplayer.h"
  2. #include <QApplication>
  3. #include <QFileInfo>
  4. #include <QSettings>
  5. #include <QIcon>
  6. #include <QDir>
  7. //! [0]
  8. static void associateFileTypes(const QStringList &fileTypes) // 这是一个helper函数,用来将某文件格式与本程序关联
  9. {
  10. QString displayName = QGuiApplication::applicationDisplayName();
  11. QString filePath = QCoreApplication::applicationFilePath();
  12. QString fileName = QFileInfo(filePath).fileName();
  13. QSettings settings("HKEY_CURRENT_USER\\Software\\Classes\\Applications\\" + fileName, QSettings::NativeFormat);
  14. settings.setValue("FriendlyAppName", displayName);
  15. settings.beginGroup("SupportedTypes");
  16. foreach (const QString& fileType, fileTypes)
  17. settings.setValue(fileType, QString());
  18. settings.endGroup();
  19. settings.beginGroup("shell");
  20. settings.beginGroup("open");
  21. settings.setValue("FriendlyAppName", displayName);
  22. settings.beginGroup("Command");
  23. settings.setValue(".", QChar('"') + QDir::toNativeSeparators(filePath) + QString("\" \"%1\""));
  24. }
  25. //! [0]
  26. int main(int argc, char *argv[])
  27. {
  28. QApplication app(argc, argv);
  29. app.setApplicationName("MusicPlayer");
  30. app.setOrganizationName("QtWinExtras");
  31. app.setOrganizationDomain("qt-project.org");
  32. app.setApplicationDisplayName("QtWinExtras Music Player");
  33. app.setWindowIcon(QIcon(":/logo.png"));
  34. associateFileTypes(QStringList(".mp3"));                // helper函数的使用方式
  35. MusicPlayer player;
  36. const QStringList arguments = QCoreApplication::arguments();
  37. if (arguments.size() > 1)                              // 如果打开参数包含文件名
  38. player.playFile(arguments.at(1));                  // 则开始播放第一首
  39. player.resize(300, 60);
  40. player.show();
  41. return app.exec();
  42. }

VolumeButton 类继承自QToolButton,使用 Qt 中的标准音量图像设置为自身图标,

  1. setIcon(style()->standardIcon(QStyle::SP_MediaVolume));

并提供了一个可以调节音量的弹出菜单,并根据DWM的混合状态决定自身的显示状态,代码都很容易理解,就不贴出来了。

在MusicPlayer类中,首先记得

  1. #include <QtWinExtras>

然后我们通过下面的函数来创建Jump Lists:

  1. void MusicPlayer::createJumpList()
  2. {
  3. QWinJumpList jumplist;
  4. jumplist.recent()->setVisible(true);
  5. }

Taskbar的创建与Progress类似,我们将其与窗口上的进度条关联起来:

  1. void MusicPlayer::createTaskbar()
  2. {
  3. taskbarButton = new QWinTaskbarButton(this);
  4. taskbarButton->setWindow(windowHandle());  // 使用窗口句柄作为参数
  5. taskbarProgress = taskbarButton->progress();
  6. connect(positionSlider, SIGNAL(valueChanged(int)), taskbarProgress, SLOT(setValue(int)));
  7. connect(positionSlider, SIGNAL(rangeChanged(int,int)), taskbarProgress, SLOT(setRange(int,int)));
  8. connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(updateTaskbar()));
  9. }

要创建预览窗口按钮,首先需要创建一个QWinThumbnailToolBar,然后在上面添加按钮:

  1. void MusicPlayer::createThumbnailToolBar()
  2. {
  3. thumbnailToolBar = new QWinThumbnailToolBar(this);
  4. thumbnailToolBar->setWindow(windowHandle());
  5. playToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
  6. playToolButton->setEnabled(false);
  7. playToolButton->setToolTip(tr("Play"));
  8. playToolButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
  9. connect(playToolButton, SIGNAL(clicked()), this, SLOT(togglePlayback()));
  10. forwardToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
  11. forwardToolButton->setEnabled(false);
  12. forwardToolButton->setToolTip(tr("Fast forward"));
  13. forwardToolButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekForward));
  14. connect(forwardToolButton, SIGNAL(clicked()), this, SLOT(seekForward()));
  15. backwardToolButton = new QWinThumbnailToolButton(thumbnailToolBar);
  16. backwardToolButton->setEnabled(false);
  17. backwardToolButton->setToolTip(tr("Rewind"));
  18. backwardToolButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekBackward));
  19. connect(backwardToolButton, SIGNAL(clicked()), this, SLOT(seekBackward()));
  20. thumbnailToolBar->addButton(backwardToolButton);
  21. thumbnailToolBar->addButton(playToolButton);
  22. thumbnailToolBar->addButton(forwardToolButton);
  23. connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(updateThumbnailToolBar()));
  24. connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(updateThumbnailToolBar()));
  25. connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(updateThumbnailToolBar()));
  26. }

最后我们看看程序运行效果:

在Win7下当我们暂停播放时,任务栏会出现一个暂停样式的图标,而在Win8中则表现为绿色的进度条变成了黄色:

http://blog.csdn.net/cloud_castle/article/details/43672509

Qt5官方demo解析集35——Music Player(使用winextras模块)的更多相关文章

  1. Qt5官方demo解析集30——Extending QML - Binding Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集29--Extendin ...

  2. Qt5官方demo解析集13——Qt Quick Particles Examples - Image Particles

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文 Qt5官方demo解析集12--Qt Quic ...

  3. Qt5官方demo解析集28——Extending QML - Signal Support Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集27--Extendin ...

  4. Qt5官方demo解析集(36个)

    http://blog.csdn.net/cloud_castle/article/category/2123873 http://blog.csdn.net/cloud_castle/article ...

  5. Qt5官方demo解析集21——Extending QML - Adding Types Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 又是一个新的系列了,只是这个系列和我们之前的Chapt ...

  6. Qt5官方demo分析集11——Qt Quick Particles Examples - Affectors

    在这个系列中的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集10--Qt ...

  7. Qt5官方demo分析集29——Extending QML - Property Value Source Example

    此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集28--Extend ...

  8. Qt5官方demo分析集10——Qt Quick Particles Examples - Emitters

    此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 前段时间去听了Qt在北京的开发人员大会,感觉QML ...

  9. 订餐系统之微信支付,踩了官方demo的坑

        最近一个项目要增加微信支付的功能,想来这个东西出来这么久了,按微信提供的应该可以很快搞定的,结果提供的demo( JS API网页支付)中各种坑,咨询他们的客服,态度倒是非常好,就是解决不了问 ...

随机推荐

  1. [RxJS] Multicasting shortcuts: publish() and variants

    Because using multicast with a new Subject is such a common pattern, there is a shortcut in RxJS for ...

  2. [array] leetCode-18. 4Sum -Medium

    18. 4Sum -Medium descrition Given an array S of n integers, are there elements a, b, c, and d in S s ...

  3. 用python的库监听鼠标程序测试,有程序,有现象

    程序如下: # -*- coding: utf-8 -*- import pythoncom, pyHook  def OnMouseEvent(event):   print 'MessageNam ...

  4. mysql 查询字段名所在的表

    select * from (select * from information_schema.COLUMNS where table_schema = '数据库名') temp where colu ...

  5. 数据类型总结——Array(数组类型)

    相关文章 简书原文:https://www.jianshu.com/p/1e4425383a65 数据类型总结——概述:https://www.cnblogs.com/shcrk/p/9266015. ...

  6. js进阶正则表达式5几个小实例(原样匹配的字符在正则中原样输出)(取反^)

    js进阶正则表达式5几个小实例(原样匹配的字符在正则中原样输出)(取反^) 一.总结 原样匹配的字符在正则中原样输出:var reg4=/第[1-2][0-9]章/g //10-29 取反^:var ...

  7. Android 异步更新UI-线程池-Future-Handler实例分析

    前言: 我们在开发Android过程中,在处理耗时任务和UI交互的过程中,都会将耗时任务放到子线程处理并刷新. 下面我提出的两个问题,相信大多数开发者都会碰到: 1. 数据经常需要读取更新,并且比较耗 ...

  8. [TypeScript] Find the repeated item in an array using TypeScript

    Say you have an array that has at least one item repeated. How would you find the repeated item. Thi ...

  9. 逐步把Nginx及Redis引入项目组之负载均衡技术调研初版总结

    本篇以一个Nginx服务.两个Tomcat服务.一个Redis搭建一个负载均衡环境,由于就一台电脑暂以随机分配client请求策略开展,详细工作中推荐以IP地址来实现client请求的动态负载策略.省 ...

  10. RSA Android加密的数据服务器上无法解密?

    一.android加密的数据服务器上无法解密? "算法/模式/填充" android的rsa加密方式是--------RSA/ECB/NoPadding或者RSA/None/NoP ...