問題:
最近寫了個(gè)項(xiàng)目,需要播放視頻并在視頻上做標(biāo)記框去完成一些功能
因?yàn)橐曨l播放使用了VLC-qt
的庫(kù),封裝好的窗口控件
沒辦法直接在該視頻窗口上繪圖(也許可以?)
出于不想動(dòng)別人寫好的庫(kù)的想法,想著在視頻窗口上加一個(gè)透明蒙版-即一個(gè)透明窗口,在透明窗口上進(jìn)行繪圖操作
實(shí)現(xiàn):
這個(gè)是業(yè)務(wù)窗口邏輯
void Dialog::on_select_videowindow_clicked()
{
//獲取本窗口中視頻窗口的位置,并轉(zhuǎn)換為相對(duì)屏幕坐標(biāo)
QPoint p = ui->video->mapToGlobal(QPoint(0, 0));
QSize size = ui->video->size();
//當(dāng)沒創(chuàng)建新創(chuàng)口界面時(shí),new一個(gè)出來
if(m_screen == NULL)
{
m_screen = new Screen(0,p.x(),p.y(),size.width(),size.height());
}
else
{
//設(shè)置回初始狀態(tài)
m_screen->init(true);
}
m_screen->show();
}
這個(gè)是透明蒙版的構(gòu)造函數(shù)
Screen::Screen(QWidget *parent, int x, int y, int w, int h)
: QWidget(parent),
m_widthInfoRect(QRectF(0, 0, 0, 0)),
m_control(NULL)
{
setWindowFlags(Qt::FramelessWindowHint);//設(shè)置無標(biāo)題欄
setMouseTracking(true);//捕獲鼠標(biāo)事件
setAttribute(Qt::WA_QuitOnClose,false);//設(shè)置本窗口不關(guān)聯(lián)程序退出
setAttribute(Qt::WA_TransparentForMouseEvents, false);//設(shè)置鼠標(biāo)不穿透
setAttribute(Qt::WA_TranslucentBackground, true);//設(shè)置窗口透明背景
setWindowFlag(Qt::WindowStaysOnTopHint);//設(shè)置本窗口處在頂層
//初始化本窗口參數(shù)
init(true);
}
分析:
如上,獲取了視頻窗口的位置及大小,并將透明窗口覆蓋在video窗口上
然后重寫了Screen的部分鼠標(biāo)事件及繪圖事件,實(shí)現(xiàn)標(biāo)記功能
但實(shí)際操作發(fā)現(xiàn),當(dāng)鼠標(biāo)點(diǎn)擊透明窗口時(shí)無法觸發(fā)該透明窗口的鼠標(biāo)事件,即鼠標(biāo)穿透了,點(diǎn)擊到了視頻窗口上。
明明已經(jīng)設(shè)置了WA_TransparentForMouseEvents
屬性為false,但鼠標(biāo)依然穿透了。
即setAttribute(Qt::WA_TransparentForMouseEvents, false)
未生效
重新實(shí)現(xiàn):
經(jīng)過一段時(shí)間的研究,將代碼修改后
重寫paintEvent
事件解決了這個(gè)問題
如下:
Screen::Screen(QWidget *parent, int x, int y, int w, int h)
: QWidget(parent),
m_widthInfoRect(QRectF(0, 0, 0, 0)),
m_control(NULL)
{
setWindowFlags(Qt::FramelessWindowHint);//設(shè)置無標(biāo)題欄
setMouseTracking(true);//捕獲鼠標(biāo)事件
m_pixmap = QPixmap(w,h);
//全局路徑的初始化,一個(gè)全屏閉合回路
m_globalPath.lineTo(m_pixmap.width(), 0);
m_globalPath.lineTo(m_pixmap.width(), m_pixmap.height());
m_globalPath.lineTo(0, m_pixmap.height());
m_globalPath.lineTo(0, 0);
setAttribute(Qt::WA_QuitOnClose,false);//設(shè)置本窗口不關(guān)聯(lián)程序退出
// setAttribute(Qt::WA_TransparentForMouseEvents, false);//設(shè)置鼠標(biāo)不穿透
setAttribute(Qt::WA_TranslucentBackground, true);//設(shè)置窗口透明背景
setWindowFlag(Qt::WindowStaysOnTopHint);//設(shè)置本窗口處在頂層
//初始化本窗口參數(shù)
init(true);
}
void Screen::paintEvent(QPaintEvent *e)
{
//解決鼠標(biāo)穿透問題
Q_UNUSED(e);
QPainter paint(this);
paint.setPen(Qt::transparent);
paint.setBrush(QColor(0, 0, 0, 1));
//關(guān)鍵是這一步 繪制一個(gè)全局的路徑
paint.drawPath(m_globalPath);
//其他繪圖事件
}
可以看到透明窗口上再繪制一個(gè)透明全屏幕路徑后完美的解決了這個(gè)問題
發(fā)現(xiàn)設(shè)不設(shè)置Qt::WA_TransparentForMouseEvents
這個(gè)屬性好像沒有什么影響,也許默認(rèn)就是false。
效果如下:
結(jié)論:
猜測(cè):就是因?yàn)楫?dāng)前窗口上什么都沒有只有一個(gè)透明背景導(dǎo)致鼠標(biāo)穿透了,再窗口上再繪制透明圖片(即讓窗口上有東西)即可解決這個(gè)問題。文章來源:http://www.zghlxwxcb.cn/news/detail-764294.html
但具體底層機(jī)制不明,還得深入學(xué)習(xí)下。
不過就目前來講,應(yīng)該夠用了。文章來源地址http://www.zghlxwxcb.cn/news/detail-764294.html
到了這里,關(guān)于Qt透明窗口鼠標(biāo)穿透問題及解決辦法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!