我正在開發PyQt5中的一個應用程式,它由一個側面選單(左側)和一個內容視窗(右側)組成:

在側面選單上,我有一個Settings QPushButton。單擊時,兩者之間會出現一個新視窗:

我想為這個視窗的顯示設定影片,以便:
- 當它出現時,它從左到右掃過;
- 當它消失時,它會從右向左掃過。
到目前為止,這是我的代碼:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
class Settings(QWidget):
def __init__(self):
super().__init__()
self.settingsFrame = QFrame(self)
self.settingsFrame.setMaximumWidth(300)
self.settingsFrame.setObjectName("Settings")
self.settingsLayout = QVBoxLayout(self.settingsFrame)
self.settingsLayout.setContentsMargins(0, 0, 0, 0)
self.settingsLayout.setSpacing(0)
self.settingsLayout.addWidget(QLabel("My settings info 1"))
self.settingsLayout.addWidget(QLabel("My settings info 2"))
self.settingsFrame.hide()
class LeftMenu(QWidget):
def __init__(self, settings_w):
super().__init__(settings_w)
self.settings_w = settings_w
self.leftMenuFrame = QFrame(self)
self.leftMenuFrame.setMaximumWidth(200)
self.leftMenuFrame.setObjectName("LeftMenu")
self.menuLayout = QVBoxLayout(self.leftMenuFrame)
self.menuLayout.setContentsMargins(0, 0, 0, 0)
self.menuLayout.setSpacing(0)
self.menuLayout.addWidget(QLabel("Some informations"))
self.menuLayout.addWidget(QLabel("Some more"))
self.menuLayout.addStretch(1)
self.but = QPushButton("Settings")
self.but.clicked.connect(self.handle_settings)
self.menuLayout.addWidget(self.but)
def handle_settings(self):
if self.settings_w.isHidden():
self.settings_w.settingsFrame.show()
else:
self.settings_w.settingsFrame.hide()
class Window(QWidget):
def __init__(self):
super().__init__()
self.windowFrame = QFrame(self)
self.windowLayout = QGridLayout(self.windowFrame)
self.windowLayout.setContentsMargins(0, 0, 0, 0)
self.windowLayout.setSpacing(0)
self.label = QLabel("CONTENT")
self.settings = Settings()
self.leftMenu = LeftMenu(self.settings)
self.windowLayout.addWidget(self.leftMenu.leftMenuFrame, 0, 0, 1, 1)
self.windowLayout.addWidget(self.settings.settingsFrame, 0, 1, 1, 1)
self.windowLayout.addWidget(self.label, 0, 2, 1, 1, Qt.AlignCenter)
self.setLayout(self.windowLayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
我想我應該使用QPropertyAnimation但我不能讓它與我的示例一起使用。
謝謝你的幫助 !
編輯:正如@ekhumoro 所建議的,這是我用QPropertyAnimation嘗試過的
if self.settings_w.isHidden():
# self.settings_w.settingsFrame.show()
animation = QPropertyAnimation(self.settings_w.settingsFrame, b"geometry")
animation.setDuration(400)
animation.setStartValue(QRect(0, 0, 0, self.settings_w.settingsFrame.height()))
animation.setEndValue(QRect(0, 0, 300, self.settings_w.settingsFrame.height()))
animation.start()
uj5u.com熱心網友回復:
您嘗試使用影片的主要問題是您將其創建為區域變數:一旦handle_settings回傳,影片就會被垃圾收集(洗掉)并且不會發生其他任何事情。
不幸的是,這還不夠,因為還有其他問題。
首先,從物件結構的角度來看,您的代碼存在一些問題:Settings和LeftMenu類都沒有真正使用,因為您實際上使用的是在它們的__init__. 這不僅在概念上是錯誤的,而且還會使您的代碼變得不必要地復雜且難以處理。
然后還有另一個問題:顯示以前隱藏的小部件會使其父布局根據新顯示的小部件的大小以及您嘗試手動設定幾何圖形的事實立即調整所有其他小部件(以及嵌套布局,如果有的話)的大小不會改變任何東西,因為布局不受手動幾何更改的影響。
解決方案(除了正確構建類之外)是使用影片子選單的固定寬度,并手動設定布局的幾何形狀。
請注意,這沒有考慮可調整大小的子選單的可能性,這會使事情變得更加復雜,因為影片應該考慮所有其他同級小部件的大小提示,以正確設定幾何圖形的最終值。在這種情況下,我只使用了提供的示例中建議的固定寬度。
class Settings(QWidget):
def __init__(self):
super().__init__()
self.setFixedWidth(0)
self.settingsLayout = QVBoxLayout(self)
self.settingsLayout.setContentsMargins(0, 0, 0, 0)
self.settingsLayout.setSpacing(0)
self.settingsLayout.addWidget(QLabel("My settings info 1"))
self.settingsLayout.addWidget(QLabel("My settings info 2"))
self.animation = QVariantAnimation(self)
self.animation.setDuration(400)
self.animation.setStartValue(0)
self.animation.setEndValue(300)
self.animation.valueChanged.connect(self.updateSize)
def updateSize(self, width):
self.setFixedWidth(width)
self.settingsLayout.setGeometry(QRect(width - 300, 0, 300, self.height()))
def toggle(self):
if self.width() and self.animation.direction() == self.animation.Forward:
self.animation.setDirection(self.animation.Backward)
else:
self.animation.setDirection(self.animation.Forward)
self.animation.start()
class LeftMenu(QFrame):
toggle_settings = pyqtSignal()
def __init__(self):
super().__init__()
self.setObjectName("LeftMenu")
self.menuLayout = QVBoxLayout(self)
self.menuLayout.setContentsMargins(0, 0, 0, 0)
self.menuLayout.setSpacing(0)
self.menuLayout.addWidget(QLabel("Some informations"))
self.menuLayout.addWidget(QLabel("Some more"))
self.menuLayout.addStretch(1)
self.but = QPushButton("Settings")
self.but.clicked.connect(self.toggle_settings)
self.menuLayout.addWidget(self.but)
self.setMaximumWidth(min(200, self.sizeHint().width()))
class Window(QWidget):
def __init__(self):
super().__init__()
self.windowFrame = QFrame(self)
self.windowLayout = QGridLayout(self.windowFrame)
self.windowLayout.setContentsMargins(0, 0, 0, 0)
self.windowLayout.setSpacing(0)
self.label = QLabel("CONTENT")
self.settings_w = Settings()
self.leftMenu = LeftMenu()
self.windowLayout.addWidget(self.leftMenu, 0, 0, 1, 1)
self.windowLayout.addWidget(self.settings_w, 0, 1, 1, 1)
self.windowLayout.addWidget(self.label, 0, 2, 1, 1, Qt.AlignCenter)
self.setLayout(self.windowLayout)
self.leftMenu.toggle_settings.connect(self.settings_w.toggle)
self.setMinimumWidth(self.minimumSizeHint().width() 300)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/407442.html
標籤:
