Почему неправильно работает растяжение виджетов PyQt5
Пытаюсь создать анимированное расширяемое меню.
Вроде бы создал, но работает криво: при его обратном закрытии кнопки не возвращаются в исходное положение.
Пытался растягивать self.vbox_1, но не получилось.
Как я могу сделать так, чтобы все виджеты растягивались и стягивались корректно?
from PyQt5.Qt import *
import sys
class Window(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.clicks = 0
self.setStyleSheet("background-color: rgb(35,35,35)")
self.setMinimumSize(1000,500)
self.top_bar = QFrame()
self.top_bar.setStyleSheet("background-color: rgb(35,35,35);")
self.top_bar.setMaximumHeight(40)
self.top_bar.setFrameShadow(QFrame.Raised)
self.content = QFrame()
self.content.setStyleSheet("background-color: rgb(45,45,45);")
self.content.setFrameShadow(QFrame.Raised)
self.left_bar = QStackedWidget()
self.left_bar.setStyleSheet("background-color: rgb(35,35,35);")
self.left_bar.setMaximumWidth(80)
self.left_bar.setFrameShadow(QFrame.Raised)
self.menu_frame = QFrame()
self.menu_frame.setFixedSize(80,40)
self.menu_frame.setStyleSheet("background-color: rgb(110, 192, 255);")
self.menu_button = QPushButton(self.menu_frame)
self.menu_button.setStyleSheet("background-color: transparent;\
border: 0px solid; font: 14pt; color: rgb(35,35,35);")
self.menu_button.setText("Menu")
self.menu_button.setMinimumSize(80,40)
self.page_1_button = QPushButton(self.left_bar)
self.page_1_button.setStyleSheet("QPushButton:hover { background-color: rgb(85,170,255) }\
QPushButton:!hover { background-color: transparent; border: 0px solid; font: 11pt; color: rgb(255,255,255) }")
self.page_1_button.setText("Page 1")
self.page_1_button.setGeometry(0,0,80,40)
self.page_2_button = QPushButton(self.left_bar)
self.page_2_button.setStyleSheet("QPushButton:hover { background-color: rgb(85,170,255) }\
QPushButton:!hover { background-color: transparent; border: 0px solid; font: 11pt; color: rgb(255,255,255) }")
self.page_2_button.setText("Page 2")
self.page_2_button.setGeometry(0, 40, 80, 40)
self.vbox_1 = QVBoxLayout()
self.vbox_1.addWidget(self.menu_frame)
self.vbox_1.addWidget(self.left_bar)
self.vbox_2 = QVBoxLayout()
self.vbox_2.addWidget(self.top_bar)
self.vbox_2.addWidget(self.content)
self.hbox = QHBoxLayout(self)
self.hbox.setContentsMargins(0, 0, 0, 0)
self.hbox.setSpacing(0)
self.hbox.addLayout(self.vbox_1)
self.hbox.addLayout(self.vbox_2)
self.menu_button.clicked.connect(self.toggle)
def toggle(self):
self.clicks+=1
array = [self.menu_frame,self.menu_button,self.left_bar,self.page_1_button,self.page_2_button]
for i in array:
self.animation = QPropertyAnimation(i, b"minimumWidth")
self.animation.setDuration(50)
if self.clicks%2 == 1:
self.animation.setStartValue(80)
self.animation.setEndValue(140)
else:
self.animation.setStartValue(140)
self.animation.setEndValue(80)
self.animation.setEasingCurve(QEasingCurve.OutBounce)
self.animation.start()
QTest.qWait(70)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
Ответы (2 шт):
Автор решения: DeMeNToR
→ Ссылка
Частично решил твою проблему, но вторая кнопка ведет себя неадекватно. Костыль, конечно, но думаю, что это даст тебе верное направление.
def toggle(self):
self.clicks+=1
array = [self.menu_frame,self.menu_button,self.left_bar,self.page_1_button,self.page_2_button]
for i in array:
self.animation = QPropertyAnimation(i, b"minimumWidth")
self.animation.setDuration(200)
if self.clicks%2 == 1:
self.animation.setStartValue(80)
self.animation.setEndValue(140)
else:
################
self.menu_button.setGeometry(0, 0, 80, 40)
self.page_1_button.setGeometry(0, 0, 80, 40)
self.page_2_button.setGeometry(0, 40, 80, 40)
################
self.animation.setStartValue(140)
self.animation.setEndValue(80)
self.animation.setEasingCurve(QEasingCurve.OutBounce)
self.animation.start()
QTest.qWait(70)
Автор решения: S. Nick
→ Ссылка
Создайте self.left_bar = QFrame()
Добавьте в left_bar кнопки.
Примените анимацию к left_bar:
self.animation = QPropertyAnimation(self.left_bar, b"minimumWidth")
import sys
from PyQt5.Qt import *
class Window(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.clicks = 0
self.setStyleSheet("background-color: rgb(35,35,35)")
self.setMinimumSize(1000, 500)
self.top_bar = QFrame()
self.top_bar.setStyleSheet("background-color: rgb(35,35,35);")
self.top_bar.setMaximumHeight(40)
self.top_bar.setFrameShadow(QFrame.Raised)
self.content = QFrame()
self.content.setStyleSheet("background-color: rgb(145,45,45);")
self.content.setFrameShadow(QFrame.Raised)
# left_bar
self.left_bar = QFrame()
self.left_bar.setStyleSheet("background-color: rgb(35,135,35);")
self.left_bar.setMaximumWidth(80)
self.left_bar.setFrameShadow(QFrame.Raised)
# menu_button
self.menu_button = QPushButton()
self.menu_button.setStyleSheet("""
background-color: #22aa55; /* transparent */
border: 0px solid;
font: 14pt;
color: rgb(235,35,35);
""")
self.menu_button.setText("Menu")
self.menu_button.setMinimumHeight(40)
self.menu_button.clicked.connect(self.toggle)
# page_1_button
self.page_1_button = QPushButton()
self.page_1_button.setStyleSheet("""
QPushButton:hover {
background-color: rgb(85,170,255)
}
QPushButton:!hover {
background-color: transparent;
border: 0px solid;
font: 11pt;
color: rgb(255,255,255)
}
""")
self.page_1_button.setText("Page 1")
self.page_1_button.setMinimumHeight(40)
# self.page_2_button
self.page_2_button = QPushButton()
self.page_2_button.setStyleSheet("""
QPushButton:hover {
background-color: rgb(85,170,255)
}
QPushButton:!hover {
background-color: transparent;
border: 0px solid;
font: 11pt;
color: rgb(255,255,255)
}
""")
self.page_2_button.setText("Page 2")
self.page_2_button.setMinimumHeight(40)
self.vbox_1 = QVBoxLayout(self.left_bar)
self.vbox_1.addWidget(self.menu_button)
self.vbox_1.addWidget(self.page_1_button)
self.vbox_1.addWidget(self.page_2_button)
self.vbox_1.addStretch()
self.vbox_1.setContentsMargins(0, 0, 0, 0)
self.right_bar = QFrame()
self.right_bar.setFrameShadow(QFrame.Raised)
self.vbox_2 = QVBoxLayout(self.right_bar)
self.vbox_2.addWidget(self.top_bar)
self.vbox_2.addWidget(self.content)
self.vbox_2.setContentsMargins(0, 0, 0, 0)
self.vbox_2.setSpacing(0)
self.hbox = QHBoxLayout(self)
self.hbox.setContentsMargins(0, 0, 0, 0)
self.hbox.setSpacing(0)
# self.hbox.addLayout(self.vbox_1)
# self.hbox.addLayout(self.vbox_2)
self.hbox.addWidget(self.left_bar)
self.hbox.addWidget(self.right_bar)
def toggle(self):
# print(f'self.left_bar.width() -- {self.left_bar.width()}') #
self.animation = QPropertyAnimation(self.left_bar, b"minimumWidth")
self.animation.setDuration(2000)
# if self.clicks%2 == 1:
if self.left_bar.width() == 80:
self.animation.setStartValue(80)
self.animation.setEndValue(140)
else:
self.animation.setStartValue(140)
self.animation.setEndValue(80)
self.animation.setEasingCurve(QEasingCurve.OutBounce)
self.animation.start()
# ??? QTest.qWait(1170)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
