## 一、前言
如果采用的vlc句柄模式,如果鼠标停留在句柄控件中会发现在打开后鼠标打圈圈,mpv句柄模式是在关闭后鼠标打圈圈,这两者真是一前一后,这种给人的体验其实很不友好的,播放开始后或者播放完成后鼠标指针居然变成了繁忙,但是当你将鼠标位置从句柄控件中移到外面的时候,他又会自动恢复,所以需要有个机制主动恢复鼠标形状,一开始想的办法是模拟移动鼠标位置移来移去,当有几十个上百个通道的时候,这样移来移去看起来就是很傻的感觉,后面想了个办法用
系统的api强制将鼠标指针恢复,测试下来还是有点怪怪的,后面发现Qt本身就内置了鼠标指针复位的函数先 qApp->setOverrideCursor(Qt::ArrowCursor) 后 qApp->restoreOverrideCursor(),就用它了。
思路这下子就清晰了,在播放打开和完成的信号中,
执行两行代码就行,为了使用起来更简便,单独开辟了一个VideoTask线程处理这个事情,这样可以过滤频繁的触发,比如64个通道同时打开,其实只需要最后那个打开完成复位下就行,并不需要执行64次,而且
线程中还可以控制延时执行,比如传入某个指令延时300ms再去执行,测试过程中也是这个情况,立即执行很可能还是不会生效,而是要延时一段时间执行才能完美生效。
## 二、效果图
## 三、体验地址
1. 国内站点:[
https://gitee.com/feiyangqingyun](https://gitee.com/feiyangqingyun)
2. 国际站点:[
https://github.com/feiyangqingyun](https://github.com/feiyangqingyun)
3. 个人作品:[
https://blog.csdn.net/feiyangqingyun/article/details/97565652](https://blog.csdn.net/feiyangqingyun/article/details/97565652)
4. 体验地址:[
https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g](https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g) 提取码:01jf
文件名:bin_video_demo/bin_linux_video。
## 四、相关代码
```cpp
void VideoTask::run()
{
while (!stopped) {
if (times.count() > 0) {
mutex.lock();
QDateTime time = times.first();
QString type = types.first();
QString para = paras.first();
mutex.unlock();
QDateTime now = QDateTime::currentDateTime();
int offset = time.msecsTo(now);
if (offset >= 500) {
//qDebug() << TIMEMS << offset << type << para;
if (type == "renameFile") {
VideoHelper::renameFile(para);
} else if (type == "resetCursor") {
//必须在主线程执行
QMetaObject::invokeMethod(this, "resetCursor");
}
//执行完成任务后从队列中移除
mutex.lock();
times.removeFirst();
types.removeFirst();
paras.removeFirst();
mutex.unlock();
}
}
msleep(100);
}
stopped = false;
}
void VideoTask::resetCursor()
{
VideoHelper::resetCursor();
}
void VideoTask::append(const
QString &type, const QString ¶)
{
//复位光标只需要一次
if (type == "resetCursor" && types.contains("resetCursor")) {
return;
}
mutex.lock();
times << QDateTime::currentDateTime();
types << type;
paras << para;
mutex.unlock();
}
void VideoWidget::receivePlayStart(int time)
{
//vlc内核句柄模式下在打开后鼠标打圈圈需要复位下
if (widgetPara.videoMode == VideoMode_Hwnd) {
VideoTask::Instance()->append("resetCursor", "");
}
//句柄模式下句柄控件要禁用绘制防止闪烁(尤其是海康大华厂家sdk内核)
if (widgetPara.videoMode == VideoMode_Hwnd && videoPara.videoCore != VideoCore_Qtav) {
hwndWidget->setUpdatesEnabled(false);
}
//执行父类处理
AbstractVideoWidget::receivePlayStart(time);
//设置默认声音大小和静音状态(测试发现Qt5.8以下的音频类需要延时设置才行)
if (videoPara.videoCore == VideoCore_FFmpeg) {
this->setMuted(widgetPara.soundMuted);
#if (QT_VERSION >= QT_VERSION_CHECK(5,8,0))
this->revolume();
#else
QTimer::singleShot(200, this, SLOT(revolume()));
#endif
} else {
this->revolume();
}
}
void VideoWidget::receivePlayFinsh()
{
//mpv内核句柄模式下在关闭后鼠标打圈圈需要复位下
if (widgetPara.videoMode == VideoMode_Hwnd) {
VideoTask::Instance()->append("resetCursor", "");
}
//句柄模式下句柄控件要禁用绘制防止闪烁(尤其是海康大华厂家sdk内核)
if (widgetPara.videoMode == VideoMode_Hwnd && videoPara.videoCore != VideoCore_Qtav) {
hwndWidget->setUpdatesEnabled(true);
}
//执行父类处理
AbstractVideoWidget::receivePlayFinsh();
}
```