Как мне скрыть из layout widget до тех пор пока не запустится анимация?
У меня есть вот такой код:
import sys
import os # +++
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, QApplication, QWidget, QMainWindow, QVBoxLayout, QLabel
from PyQt5.QtQml import QQmlApplicationEngine
DIR_PATH = os.path.dirname(os.path.realpath(__file__)) # +++
#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(maximumWidth=30, minimumWidth=0)
#self.menu_pos_block.setGeometry(QRect(40, 20, 0, 0))
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, widget, parent=None):
super().__init__(parent)
self.toggle_animations = QtCore.QSequentialAnimationGroup(self)
self.toggle_animation = QtCore.QParallelAnimationGroup(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")
menu_layout.setSpacing(0)
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)
# conect menu and but
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])
#retutn element с _expand = True
for menu in sorted(self.menu_pos_ter, key=lambda x: x._expand):
menu_width = 74 #menu.width()
menu_height = 81#menu.height()
menu.setMaximumSize(QSize(16777215, 16777215))
pos1 = QRect( self.menu_block_but.x() - menu_width, menu.y(),menu_width,menu_height)
pos2 = QRect( self.menu_block_but.x() +self.menu_block_but.width(), menu.y(),menu_width,menu_height)
pos3 = QRect(menu.width(),menu.height(), menu.x(), menu.y())
anims = QPropertyAnimation(menu, b"maximumWidth")
anims.setDuration(1000)
anims.setStartValue(30)
anims.setEndValue(100)
print(menu.width())
print(menu.height())
print("--x--")
print( menu.x())
print( 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 = pos2
end_pos = pos1
anim = QPropertyAnimation(menu, b"geometry")
anim.setDuration(1000)
anim.setStartValue(start_pos)
anim.setEndValue(end_pos)
self.toggle_animations.addAnimation(anim)
self.toggle_animation.addAnimation(anims)
self.toggle_animation.addAnimation(self.toggle_animations)
if (self.num == 1) or (self.num == 3):
self.toggle_animation.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)
#load qml
file = os.path.join(DIR_PATH, "qml_window.qml") # +++
url = QUrl.fromLocalFile(file) # +++
engine = QQmlApplicationEngine()
context = engine.rootContext()
context.setContextProperty("main", engine)
engine.load(url)
if not engine.rootObjects():
sys.exit(-1)
widget = QWidget.createWindowContainer(engine.rootObjects()[0])
w = MainWindow(widget)
w.resize(640, 570) #Size window
w.show()
sys.exit(app.exec_())
При нажатии на radio widget улетает в бок, а место, которое он занимал остается.
Я хочу скрыть widget за границы layout родителя и при нажатии radio выдвигать его.
Но проблема в том, что я не могу менять размер widgets внутри layout команду
self.menu_pos_block.setGeometry(QRect(40, 20, 0, 0))
он не воспринимает а если я добавляю
self.menu_pos_block = QtWidgets.QWidget(maximumWidth=0, minimumWidth=0)
то уже
QRect( self.menu_block_but.x() - menu_width, menu.y(),menu_width,menu_height)
не реагирует на мои команды еще раз уточняю что до включения radio весь widget должен выглядеть вот так
а уже после нажатия кнопки выдвигаться из границ layout родителя в нужную сторону.
Ответы (1 шт):
Тяжелый код. Чтобы немного понять, что происходит,
я отключил app.setStyleSheet(StyleSheet) и
установил в некоторых местах setStyleSheet, чтобы видеть где-какой виджет.
Убрал menu_layout.addWidget(self.menu_pos[i]),
т.к. управлять геометрией в макете не возможно.
Обратите внимание на расчет pos1 и pos2
и др. отмеченное в тексте.
Пробуйте.
import sys
import os
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint,
QRect, QSize, QUrl, Qt, QPropertyAnimation)
from PyQt5.QtWidgets import QGraphicsEffect, QApplication, QWidget, QMainWindow,\
QVBoxLayout, QLabel
from PyQt5.QtQml import QQmlApplicationEngine
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
#class test_mynu(QtWidgets.QWidget):
class Test_Menu(QtWidgets.QWidget):
def __init__(self, arr="", parent=None):
super(Test_Menu, self).__init__(parent)
self._expand = False
self.setStyleSheet('background:#0f0; color:#000;') # + уберете
self.menu_pos_block = QtWidgets.QWidget(maximumWidth=30, minimumWidth=0)
blur = QtWidgets.QGraphicsBlurEffect(blurRadius=1) # 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_label.setText(arr[-2:]) # установите свое
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):
def num(self):
return 3
def __init__(self, widget, parent=None):
super().__init__(parent)
self.toggle_animations = QtCore.QSequentialAnimationGroup(self)
self.toggle_animation = QtCore.QParallelAnimationGroup(self)
centralwidget = QtWidgets.QWidget(objectName="centralwidget")
self.setCentralWidget(centralwidget)
central_w_layout = QtWidgets.QGridLayout(centralwidget, objectName="central_w_layout")
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)
self.block = QtWidgets.QWidget()
self.block.setObjectName(u"block")
self.x, self.y = 166, 205 # +
QtCore.QTimer.singleShot(100, self.start_x_y) # +++
self.block.setStyleSheet('background:#f99; color:#00f;') # + уберете
central_w_layout.addWidget(self.block, 1, 1, 1, 1)
layout_block = QtWidgets.QVBoxLayout(self.block)
layout_block.setObjectName(u"layout_block")
menu_block = QtWidgets.QWidget()
menu_block.setObjectName(u"menu_block")
menu_block.setStyleSheet('background:#ff9; color:#0ff;') # + уберете
layout_block.addWidget(menu_block)
#------menu_layout------
menu_layout = QtWidgets.QHBoxLayout(menu_block)
menu_layout.setObjectName(u"menu_layout")
menu_layout.setSpacing(10) # 0 установите свое
self.menu_but = []
self.menu_pos = []
self.menu_by_pos = None
for i in range(self.num()):
menu_pos_block = Test_Menu("menu_{}".format(i), self) # + , self !!!
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))
self.menu_pos[i].setGeometry(QRect(-10, -10, 0, 0)) # +
self.menu_pos[i].show() # +
# 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)
# conect menu and but
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 = []
self.menu_nums = [] # +++
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])
#retutn element с _expand = True
for menu in sorted(self.menu_pos_ter, key=lambda x: x._expand):
menu_width = 74 # menu.width()
menu_height = 81 # menu.height()
menu.setMaximumSize(QSize(16777215, 16777215))
if self.menu_nums: # +
self.menu_nums = [self.menu_nums[-1],] # +
self.menu_nums.append(menu) # +
pos1 = QRect(self.x, #self.menu_block_but.x() - menu_width,
self.y, #menu.y(),
menu_width,
menu_height)
pos2 = QRect(self.x+200, #self.menu_block_but.x() + self.menu_block_but.width(),
self.y, # menu.y(),
menu_width,
menu_height)
# ??? pos3 = QRect(menu.width(), menu.height(), menu.x(), menu.y())
anims = QPropertyAnimation(menu, b"maximumWidth")
anims.setDuration(1000)
anims.setStartValue(30)
anims.setEndValue(100)
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 = pos2
end_pos = pos1
anim = QPropertyAnimation(menu, b"geometry")
anim.setDuration(1000)
anim.setStartValue(start_pos)
anim.setEndValue(end_pos)
self.toggle_animations.addAnimation(anim)
#? self.toggle_animation.addAnimation(anims) # - ???
self.toggle_animation.addAnimation(self.toggle_animations)
if (self.num == 1) or (self.num == 3):
self.toggle_animation.start()
self.menu_pos_ter.clear()
if self.num == 3 :
self.num = 1
# ++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def start_x_y(self):
self.x, self.y = self.block.x()-100, self.block.y()+20
def resizeEvent(self, event):
self.x, self.y = self.block.x()-100, self.block.y()+20
[ i.move(-100, 0) for i in self.menu_pos]
for i, menu in enumerate(reversed(self.menu_nums)):
if i == 0: menu.move(self.x+200, self.y)
else: menu.move(self.x, self.y)
# ++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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) # !!! установите
#load qml
file = os.path.join(DIR_PATH, "qml_window.qml")
url = QUrl.fromLocalFile(file)
engine = QQmlApplicationEngine()
context = engine.rootContext()
context.setContextProperty("main", engine)
engine.load(url)
if not engine.rootObjects():
sys.exit(-1)
widget = QWidget.createWindowContainer(engine.rootObjects()[0])
w = MainWindow(widget)
w.resize(640, 570) #Size window
w.show()
sys.exit(app.exec_())


