带有透明圆边的按钮无法在嵌入LibVLC的widget上方正确绘制
The button with transparent circular edge cannot be drawn correctly above the widget embedded with LibVLC
我有一个用LibVLC播放视频的程序,我想在VLC Widget上面放一些圆形按钮来实现弹幕效果。
这是我的测试代码。
# -*- coding: utf-8 -*-
import sys
import os
import vlc
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
class demo_widget(QWidget):
def __init__(self):
super(demo_widget, self).__init__()
self.__ui__()
def __ui__(self):
self.resize(600, 400)
t_lay_parent = QHBoxLayout()
t_lay_parent.setContentsMargins(0, 0, 0, 0)
self.frame_media = QFrame(self)
t_lay_parent.addWidget(self.frame_media)
self.setLayout(t_lay_parent)
self.pushButton_test = QPushButton("Test", self)
self.pushButton_test.setFixedSize(70, 30)
self.pushButton_test.setStyleSheet("QPushButton{background-color:#36404A;border:1px solid #36404A;border-radius:10px;color:#98A6AD;}")
self.pushButton_test.move(265, 185)
self.pushButton_test.clicked.connect(self.slt_play)
self.instance = vlc.Instance("--network-caching=1000 --http-continuous")
self.player = self.instance.media_player_new()
if sys.platform.startswith('linux'): # for Linux using the X Server
self.player.set_xwindow(self.frame_media.winId())
elif sys.platform == "win32": # for Windows
self.player.set_hwnd(self.frame_media.winId())
elif sys.platform == "darwin": # for MacOS
self.player.set_nsobject(self.frame_media.winId())
def slt_play(self):
media = self.instance.media_new("1111.m4v")
self.player.set_media(media)
self.player.play()
app = QApplication(sys.argv)
demo = demo_widget()
demo.show()
sys.exit(app.exec_())
这是理想的工作截图。
但它实际上会产生白边。
我尝试将以下设置添加到按钮,它按预期成功运行,但 运行 在 window 之外。
self.pushButton_test.setWindowFlags(Qt.SplashScreen | Qt.FramelessWindowHint)
self.pushButton_test.setAttribute(Qt.WA_TranslucentBackground, True)
有没有更好的方法画一个t运行sparent圆角的按钮?
一个可能的解决方案是使用 QRegion
和 setMask()
:
# -*- coding: utf-8 -*-
import sys
import os
import vlc
from PySide2 import QtCore, QtGui, QtWidgets
class RoundButton(QtWidgets.QPushButton):
def __init__(self, radius, *args, **kwargs):
super(RoundButton, self).__init__(*args, **kwargs)
self._radius = radius
def resizeEvent(self, event):
r = self.rect()
rb = QtCore.QRect(0, 0, 2*self._radius, 2*self._radius)
reg = QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
rb.moveRight(r.right())
reg += QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
rb.moveBottom(r.bottom())
reg += QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
rb.moveLeft(r.left())
reg += QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
reg += QtGui.QRegion(self._radius, 0, r.width() - 2*self._radius, r.height())
reg += QtGui.QRegion(0, self._radius, r.width(), r.height() - 2*self._radius)
self.setMask(reg)
super(RoundButton, self).resizeEvent(event)
class demo_widget(QtWidgets.QWidget):
def __init__(self):
super(demo_widget, self).__init__()
self.__ui__()
def __ui__(self):
self.resize(600, 400)
t_lay_parent = QtWidgets.QHBoxLayout(self)
t_lay_parent.setContentsMargins(0, 0, 0, 0)
self.frame_media = QtWidgets.QFrame()
t_lay_parent.addWidget(self.frame_media)
self.pushButton_test = RoundButton(10, "Test", self)
self.pushButton_test.setFixedSize(70, 30)
self.pushButton_test.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.pushButton_test.setStyleSheet("""QPushButton{
background-color:#36404A;
border:1px solid #36404A;
color:#98A6AD;
}""")
self.pushButton_test.move(265, 185)
self.pushButton_test.clicked.connect(self.slt_play)
self.instance = vlc.Instance("--network-caching=1000 --http-continuous")
self.player = self.instance.media_player_new()
if sys.platform.startswith('linux'): # for Linux using the X Server
self.player.set_xwindow(self.frame_media.winId())
elif sys.platform == "win32": # for Windows
self.player.set_hwnd(self.frame_media.winId())
elif sys.platform == "darwin": # for MacOS
self.player.set_nsobject(self.frame_media.winId())
def slt_play(self):
media = self.instance.media_new("1111.m4v")
self.player.set_media(media)
self.player.play()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
demo = demo_widget()
demo.show()
sys.exit(app.exec_())
我有一个用LibVLC播放视频的程序,我想在VLC Widget上面放一些圆形按钮来实现弹幕效果。
这是我的测试代码。
# -*- coding: utf-8 -*-
import sys
import os
import vlc
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
class demo_widget(QWidget):
def __init__(self):
super(demo_widget, self).__init__()
self.__ui__()
def __ui__(self):
self.resize(600, 400)
t_lay_parent = QHBoxLayout()
t_lay_parent.setContentsMargins(0, 0, 0, 0)
self.frame_media = QFrame(self)
t_lay_parent.addWidget(self.frame_media)
self.setLayout(t_lay_parent)
self.pushButton_test = QPushButton("Test", self)
self.pushButton_test.setFixedSize(70, 30)
self.pushButton_test.setStyleSheet("QPushButton{background-color:#36404A;border:1px solid #36404A;border-radius:10px;color:#98A6AD;}")
self.pushButton_test.move(265, 185)
self.pushButton_test.clicked.connect(self.slt_play)
self.instance = vlc.Instance("--network-caching=1000 --http-continuous")
self.player = self.instance.media_player_new()
if sys.platform.startswith('linux'): # for Linux using the X Server
self.player.set_xwindow(self.frame_media.winId())
elif sys.platform == "win32": # for Windows
self.player.set_hwnd(self.frame_media.winId())
elif sys.platform == "darwin": # for MacOS
self.player.set_nsobject(self.frame_media.winId())
def slt_play(self):
media = self.instance.media_new("1111.m4v")
self.player.set_media(media)
self.player.play()
app = QApplication(sys.argv)
demo = demo_widget()
demo.show()
sys.exit(app.exec_())
这是理想的工作截图。
但它实际上会产生白边。
我尝试将以下设置添加到按钮,它按预期成功运行,但 运行 在 window 之外。
self.pushButton_test.setWindowFlags(Qt.SplashScreen | Qt.FramelessWindowHint)
self.pushButton_test.setAttribute(Qt.WA_TranslucentBackground, True)
有没有更好的方法画一个t运行sparent圆角的按钮?
一个可能的解决方案是使用 QRegion
和 setMask()
:
# -*- coding: utf-8 -*-
import sys
import os
import vlc
from PySide2 import QtCore, QtGui, QtWidgets
class RoundButton(QtWidgets.QPushButton):
def __init__(self, radius, *args, **kwargs):
super(RoundButton, self).__init__(*args, **kwargs)
self._radius = radius
def resizeEvent(self, event):
r = self.rect()
rb = QtCore.QRect(0, 0, 2*self._radius, 2*self._radius)
reg = QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
rb.moveRight(r.right())
reg += QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
rb.moveBottom(r.bottom())
reg += QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
rb.moveLeft(r.left())
reg += QtGui.QRegion(rb, QtGui.QRegion.Ellipse)
reg += QtGui.QRegion(self._radius, 0, r.width() - 2*self._radius, r.height())
reg += QtGui.QRegion(0, self._radius, r.width(), r.height() - 2*self._radius)
self.setMask(reg)
super(RoundButton, self).resizeEvent(event)
class demo_widget(QtWidgets.QWidget):
def __init__(self):
super(demo_widget, self).__init__()
self.__ui__()
def __ui__(self):
self.resize(600, 400)
t_lay_parent = QtWidgets.QHBoxLayout(self)
t_lay_parent.setContentsMargins(0, 0, 0, 0)
self.frame_media = QtWidgets.QFrame()
t_lay_parent.addWidget(self.frame_media)
self.pushButton_test = RoundButton(10, "Test", self)
self.pushButton_test.setFixedSize(70, 30)
self.pushButton_test.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.pushButton_test.setStyleSheet("""QPushButton{
background-color:#36404A;
border:1px solid #36404A;
color:#98A6AD;
}""")
self.pushButton_test.move(265, 185)
self.pushButton_test.clicked.connect(self.slt_play)
self.instance = vlc.Instance("--network-caching=1000 --http-continuous")
self.player = self.instance.media_player_new()
if sys.platform.startswith('linux'): # for Linux using the X Server
self.player.set_xwindow(self.frame_media.winId())
elif sys.platform == "win32": # for Windows
self.player.set_hwnd(self.frame_media.winId())
elif sys.platform == "darwin": # for MacOS
self.player.set_nsobject(self.frame_media.winId())
def slt_play(self):
media = self.instance.media_new("1111.m4v")
self.player.set_media(media)
self.player.play()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
demo = demo_widget()
demo.show()
sys.exit(app.exec_())