Могу ли я размыть фон за qwidget «menu_pos_»? - PullRequest
0 голосов
/ 24 февраля 2020

Мне нужно сделать фон блока "menu_pos_" прозрачным и размыть все на спине. И оставьте текст понятным. Этот эффект обычно называют эффектом матового стекла.

image

Но, к сожалению, я мог только размыть весь виджет

image

import sys


from PyQt5.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint,
    QRect, QSize, QUrl, Qt)
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5.QtCore import QPropertyAnimation, QPoint

from PyQt5.QtWidgets import QGraphicsEffect

#Or

'''
from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint,
    QRect, QSize, QUrl, Qt)
from PySide2 import QtWidgets
from PySide2 import QtGui
from PySide2 import QtCore
from PySide2.QtCore import QPropertyAnimation, QPoint

from PySide2.QtWidgets import QGraphicsEffect
'''



class test_mynu(QtWidgets.QWidget):
    def __init__(self, arr="", parent=None):
        super(test_mynu, self).__init__(parent)
        self._expand = False                                # - self.__expand ; + self._expand  !!!
        #------menu_pos_block------
        self.menu_pos_block = QtWidgets.QWidget()

        blur = QtWidgets.QGraphicsBlurEffect(blurRadius=5)
        self.menu_pos_block.setGraphicsEffect(blur)


        #------menu_pos_block_layout------
        self.menu_pos_block_layout = QtWidgets.QHBoxLayout(self.menu_pos_block)
        self.menu_pos_block_layout.setObjectName(u"menu_pos_block_layout")
        #------menu_pos_label------
        self.menu_pos_label = QtWidgets.QLabel()
        self.menu_pos_label.setText(arr)
        self.menu_pos_block_layout.addWidget(self.menu_pos_label)
        #------ADD------
        lay = QtWidgets.QHBoxLayout(self)
        lay.addWidget(self.menu_pos_block)



class MainWindow(QtWidgets.QMainWindow):
    # number of radio
    def num(self):
        return 3
    def __init__(self, parent=None):
        super().__init__(parent)

        self.toggle_animations = QtCore.QSequentialAnimationGroup(self)

        #------centralwidget------
        centralwidget = QtWidgets.QWidget()
        centralwidget.setObjectName(u"centralwidget")
        self.setCentralWidget(centralwidget)
        #------layout------
        central_w_layout = QtWidgets.QGridLayout(centralwidget)
        central_w_layout.setObjectName(u"central_w_layout")
        #------Spacer------
        vs_up = QtWidgets.QSpacerItem(17, 105, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        central_w_layout.addItem(vs_up, 0, 1, 1, 1)
        hs_left = QtWidgets.QSpacerItem(327, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        central_w_layout.addItem(hs_left, 1, 0, 1, 1)
        hs_right = QtWidgets.QSpacerItem(326, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        central_w_layout.addItem(hs_right, 1, 2, 1, 1)
        vs_down = QtWidgets.QSpacerItem(20, 105, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        central_w_layout.addItem(vs_down, 2, 1, 1, 1)
        #------block------
        block = QtWidgets.QWidget()
        block.setObjectName(u"block")
        central_w_layout.addWidget(block, 1, 1, 1, 1)             ######
        #------layout------
        layout_block = QtWidgets.QVBoxLayout(block)
        layout_block.setObjectName(u"layout_block")
        #------menu_block------
        menu_block = QtWidgets.QWidget()
        menu_block.setObjectName(u"menu_block")
        layout_block.addWidget(menu_block)             ######
        #------menu_layout------
        menu_layout = QtWidgets.QHBoxLayout(menu_block)
        menu_layout.setObjectName(u"menu_layout")

        self.menu_but = []
        self.menu_pos = []
        self.menu_by_pos = None

        for i in range(self.num()):
            menu_pos_block = test_mynu("menu_{}".format(i))
            menu_pos_block.setObjectName("menu_pos_{}".format(i))

            self.menu_pos.append(menu_pos_block)
            self.menu_pos[i].setGeometry(QRect(menu_pos_block.width(), menu_pos_block.height(), 151, 181))
            menu_layout.addWidget(self.menu_pos[i])

        #------menu_block_but------
        self.menu_block_but = QtWidgets.QWidget()
        self.menu_block_but.setObjectName(u"menu_block_but")
        menu_layout.addWidget(self.menu_block_but)             ######
        #------menu_block_but_layout------
        menu_block_but_layout = QtWidgets.QVBoxLayout(self.menu_block_but)
        menu_block_but_layout.setObjectName(u"menu_block_but_layout")
        #------menu_but_radio------
        for i in range(self.num()):
            menu_but_radio = QtWidgets.QRadioButton('{}'.format(i))
            menu_but_radio.setObjectName("{}".format(i))
            menu_but_radio.toggled.connect(self.menu_animation)

            self.menu_but.append(menu_but_radio)
            menu_block_but_layout.addWidget(menu_but_radio)

        # Связывание меню к кнопкам и наоборот
        self.menu_by_but = dict()
        self.but_by_menu = dict()
        for i in range(self.num()):
            but = self.menu_but[i]
            menu = self.menu_pos[i]

            self.menu_by_but[menu] = but
            self.but_by_menu[but] = menu

        menu_block_content = QtWidgets.QWidget()
        menu_block_content.setObjectName(u"menu_block_content")
        menu_layout.addWidget(menu_block_content)             ######
        #------menu_content_layout------
        menu_content_layout = QtWidgets.QHBoxLayout(menu_block_content)
        menu_content_layout.setObjectName(u"menu_content_layout")
        #------menu_label------
        menu_label = QtWidgets.QLabel()
        menu_label.setText('text, text text, text')
        menu_content_layout.addWidget(menu_label)

        self.num = 0
        self.menu_pos_ter = []

    def menu_animation(self):
        self.num =self.num+1
        self.toggle_animations.clear()

        num = int(self.sender().objectName())
        self.menu_pos_ter.append(self.menu_pos[num])

        # Хитрая сортировка, что сначала вернет элемент с _expand = True
        for menu in sorted(self.menu_pos_ter, key=lambda x: x._expand):
            pos1 = QPoint(self.menu_block_but.x() - menu.width(), menu.y())
            pos2 = QPoint(self.menu_block_but.x() +self.menu_block_but.width(), menu.y())

            but = self.menu_by_but[menu]
            menu.raise_()
            self.menu_block_but.raise_()
            if but.isChecked():

                start_pos = pos1
                end_pos = pos2
            else:
                start_pos = menu.pos()
                end_pos = pos1

            anim = QPropertyAnimation(menu, b"pos")
            anim.setDuration(1000)
            anim.setStartValue(start_pos)
            anim.setEndValue(end_pos)

            self.toggle_animations.addAnimation(anim)


        if (self.num == 1) or (self.num == 3):
            self.toggle_animations.start()
            self.menu_pos_ter.clear()

        if self.num == 3 :
            self.num = 1
        print("--x--")


StyleSheet = """
#centralwidget QWidget QWidget,
#centralwidget QWidget QWidget QWidget QWidget,
#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget,
#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget,
#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget{
background:#000;
color:#fff;
}
#centralwidget QWidget,
#centralwidget QWidget QWidget QWidget,
#centralwidget QWidget QWidget QWidget QWidget QWidget,
#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget,
#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget{
background:#fff;
color:#000;
}
#click_me{
background:#000;
color:#fff;
}
"""

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    app.setStyleSheet(StyleSheet)
    w = MainWindow()
    w.resize(640, 570) #Size window
    w.show()
    sys.exit(app.exec_())

Я хочу, чтобы виджет выглядел следующим образом html шаблон.

$(".menu-btn input").change(function() {
$('.menu_1').removeClass('menu_1_active');
$('.menu_2').removeClass('menu_2_active'); $('.menu_3').removeClass('menu_3_active');
 
 $('.sidebar_menu_1').removeClass('sidebar_menu_1_active');
 $('.frame_menu_1').removeClass('frame_menu_1_active'); 
 
  $('.sidebar_menu_2').removeClass('sidebar_menu_2_active');
 $('.frame_menu_2').removeClass('frame_menu_2_active'); 
  
  $('.sidebar_menu_3').removeClass('sidebar_menu_3_active');
 $('.frame_menu_3').removeClass('frame_menu_3_active'); 
  
  
var name = $(this).val();

setTimeout(function(){ 

$('.menu_'+name).toggleClass('menu_'+name+'_active'); 
$('.sidebar_menu_'+name).toggleClass('sidebar_menu_'+name+'_active'); 
$('.frame_menu_'+name).toggleClass('frame_menu_'+name+'_active');  
}, 1000);


  
  
  
});


/*return*/
$("#block_blur").append('<div class="frame_menu_1" ><div class="full sidebar_menu_1"></div></div>');

$("#block_blur").append('<div class="frame_menu_2" ><div class="full sidebar_menu_2"></div></div>');

$("#block_blur").append('<div class="frame_menu_3" ><div class="full sidebar_menu_3"></div></div>');





/*copy menu */
$('.copy').clone().appendTo('.full');
.content > h3{
  padding:10px;
  margin:2px;
}

.title_1{
 background:red;
}
.title_2{
 background:blue;
}
.title_3{
 background:green;
}

.title_4{
 background:url('https://i.ytimg.com/vi/slZdLNewXrE/maxresdefault.jpg');
}

.title_5{
 background:yellow;
}


.menu-btn {
 display: flex;
  flex-direction: column;
  background-color: #333;
  position: absolute;
  left: 10px;
  top: 10px;
  z-index:110;
}

.menu-btn > input{
 margin:2px;
}

.menu > div{
   width: 200px;
  height: 200px;
  background-color:#18182178;
  position: absolute;
  left: 0px;
  top: 0px;
text-align: center;
  color:white;
transition:  1s;
  transform: translateX(-100%);
   z-index:100;
}

.menu .menu_1_active,
.menu .menu_2_active,
.menu .menu_3_active{
 transform: translateX(0%);
}


/*blur*/
.frame_menu_1,
.frame_menu_2,
.frame_menu_3{
z-index: 10;
overflow: hidden;
position: absolute;
width: 200px !important;
height:  200px !important;
top: 200px !important;
left: 0px !important;
transition:  1s;
transform: translate(0%, -100%);

 transform: translate(-100%, -100%); 
  
  
}




 .frame_menu_1_active,
 .frame_menu_2_active,
 .frame_menu_3_active{
transition:  1s; 
transform: translate(-100%, -100%);
   
   
   transform: translate(0%, -100%);
   
   
 }   









/*copy*/
.sidebar_menu_1,
.sidebar_menu_2,
.sidebar_menu_3{
width: 100% !important;
height: 100% !important;
position: absolute;
filter:blur(8px);
-webkit-filter:blur(8px);
top:  -200px;
left: 0px;
transition:  1s;
transform: translate(0%, 100%);
  
transform: translate(100%, 100% );  
  
}




 






/*active*/
.sidebar_menu_1_active,
.sidebar_menu_2_active,
.sidebar_menu_3_active{
transition:  1s; 
transform: translate(100%, 100% );
  
  
  transform: translate(0%, 100%);
  
}

 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="copy">


<div class="menu-btn">
<input type="radio" id="rad_men" name="red" value="1"/>
    <input type="radio" id="rad_men" name="red" value="2"/>
    <input type="radio" id="rad_men" name="red" value="3"/>
  
  
</div>
  
<div class="menu">
<div class="menu_1">menu 1</div>
<div class="menu_2">menu 2</div>
<div class="menu_3">menu 3</div>  
</div>
  
  


  <div class="content">
  <h3  class="title_1" >text text text</h3>
  <h3  class="title_2" >text text text</h3>
  <h3  class="title_3" >text text text</h3>
  <h3  class="title_4" >text text text</h3>
  <h3  class="title_5" >text text text</h3>
   </div>

     
     
</div>

  
 <div id="block_blur"></div>

Мне пришлось использовать JS, чтобы скопировать весь код HTML, переполнение кадра: скрыто; и синхронизировать движения с кнопками.

Если возможно, я бы хотел избежать этого метода, потому что это самый дикий ужас.

1 Ответ

1 голос
/ 25 февраля 2020

QGraphicsEffect влияет на виджет и дочерние элементы виджета, поэтому также затрагивается QLabel. Чтобы избежать этого, возможное решение состоит в том, чтобы использовать QWidget, в котором другой макет QWidget установлен с помощью макета, и к этому последнему виджету применить эффект, и добавить QLabel к исходному QWidget, чтобы QLabel и QWidget эффективно имели одинаковые родительский метод, необходимо использовать Повышение_ (), чтобы QLabel был сверху всех:

from PyQt5 import QtCore, QtGui, QtWidgets


class BlurLabel(QtWidgets.QWidget):
    def __init__(self, text, parent=None):
        super().__init__(parent)
        self.setAttribute(QtCore.Qt.WA_StyledBackground)
        widget = QtWidgets.QWidget()
        widget.setStyleSheet("""QWidget{ background:#fff; color:#000;}""")
        blur_effect = QtWidgets.QGraphicsBlurEffect(blurRadius=5)
        widget.setGraphicsEffect(blur_effect)

        self._label = QtWidgets.QLabel(
            text=text, alignment=QtCore.Qt.AlignCenter, parent=self
        )
        self.label.setStyleSheet(""" background-color : transparent; color : black""")
        self.label.setContentsMargins(10, 0, 10, 0)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(widget)

    @property
    def label(self):
        return self._label

    def sizeHint(self):
        return self._label.sizeHint()

    def resizeEvent(self, event):
        self._label.resize(self.size())
        self._label.raise_()
        return super().resizeEvent(event)


class ButtonWidget(QtWidgets.QWidget):
    clicked = QtCore.pyqtSignal(int)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAttribute(QtCore.Qt.WA_StyledBackground)
        self.setStyleSheet("""background:#fff;""")

        vlay = QtWidgets.QVBoxLayout(self)

        group = QtWidgets.QButtonGroup(self)
        group.buttonClicked[int].connect(self.clicked)

        for i in range(3):
            radiobutton = QtWidgets.QRadioButton(str(i))
            radiobutton.setStyleSheet("""background:#000; color:#fff;""")
            group.addButton(radiobutton, i)
            vlay.addWidget(radiobutton)


class LabelWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAttribute(QtCore.Qt.WA_StyledBackground)
        self.setStyleSheet("""background:#fff;""")

        vlay = QtWidgets.QVBoxLayout(self)

        label = QtWidgets.QLabel("text, text, text, text")
        label.setStyleSheet("""background:#000; color:#fff;""")
        vlay.addWidget(label)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        container = QtWidgets.QWidget()
        container.setStyleSheet("""QWidget{ background:#000;}""")

        hlay_menus = QtWidgets.QHBoxLayout()
        hlay_menus.setContentsMargins(0, 6, 0, 6)

        self.menus = []

        for i in range(3):
            menu = BlurLabel("menu-{}".format(i))
            hlay_menus.addWidget(menu)
            self.menus.append(menu)

        self.button_widget = ButtonWidget()
        self.button_widget.clicked.connect(self.onClicked)
        self.label_widget = LabelWidget()

        lay = QtWidgets.QHBoxLayout(container)
        lay.addLayout(hlay_menus)
        lay.addWidget(self.button_widget)
        lay.addWidget(self.label_widget)
        container.setFixedSize(container.sizeHint())

        hlay = QtWidgets.QHBoxLayout()
        hlay.addStretch(0)
        hlay.addWidget(container)
        hlay.addStretch(0)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        vlay = QtWidgets.QVBoxLayout(central_widget)
        vlay.addStretch(0)
        vlay.addLayout(hlay)
        vlay.addStretch(0)

        self.last_id = -1

    @QtCore.pyqtSlot(int)
    def onClicked(self, id_):
        menu = self.menus[id_]
        if not hasattr(menu, "animation"):
            animation = QtCore.QPropertyAnimation(menu, b"pos", duration=1000)
            animation.setStartValue(menu.pos())
            animation.setEndValue(
                QtCore.QPoint(self.label_widget.pos().x() + 5, menu.pos().y())
            )
            animation.start()
            menu.animation = animation

        if self.last_id != -1:
            last_menu = self.menus[self.last_id]
            last_menu.animation.setDirection(QtCore.QAbstractAnimation.Backward)
            last_menu.animation.start()
            last_menu.raise_()
        menu.animation.setDirection(QtCore.QAbstractAnimation.Forward)
        menu.animation.start()
        menu.raise_()
        self.button_widget.raise_()
        self.last_id = id_


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...