Кнопка с прозрачным круглым краем не может быть правильно нарисована над виджетом, встроенным в LibVLC - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть программа, которая воспроизводит видео с помощью LibVLC, и я хочу поместить несколько круглых кнопок поверх виджета VLC для создания эффекта заграждения.

Это мой тестовый код.

# -*- 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_())

Это идеальный рабочий скриншот.enter image description here

Но на самом деле это дает белые края.enter image description here

Я попытался добавить следующие параметры к кнопке, и она успешно работала, как и ожидалось, но она вышла за пределы окна.

self.pushButton_test.setWindowFlags(Qt.SplashScreen | Qt.FramelessWindowHint)
self.pushButton_test.setAttribute(Qt.WA_TranslucentBackground, True)

ЕстьЕсть ли лучший способ нарисовать кнопку с прозрачным круглым углом?

1 Ответ

0 голосов
/ 21 сентября 2018

Возможное решение - использовать 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_())
...