如何构建在pyqt上鼠标悬停时显示的侧边栏菜单?
How to build Side Bar Menu which shows on mouse hover on pyqt?
我一直在尝试构建一个具有动态侧边栏的应用程序。我正在使用 qtdesigner 和 pyqt5。我尝试了两种方式:
1) 使用悬停样式表。但是侧边栏(框架)上有按钮。碰巧当我看到栏时,我只能看到鼠标处于打开状态的按钮。
样式表代码:
QFrame {
background-color: rgba(255, 151, 231, 0);
}
QFrame:hover {
background-color:rgba(255, 151, 231, 0.45)
}
QPushButton {
color: rgba(0, 0, 0, 0);
background-color: rgba(255, 151, 231, 0);
}
QPushButton:hover {
background-color:rgba(255, 151, 231, 0.45);
}
输出:(鼠标在按钮上)
我知道为什么会这样,但我不知道怎么解决。
2) 使用事件
使用事件我可以达到我想要的,但我不确定我是否做对了。
class TelaPrincipal(QDialog, QMainWindow, Ui_Form):
def __init__(self, parent=None):
super(TelaPrincipal, self).__init__(parent)
QDialog.__init__(self, parent)
Ui_Form.__init__(self)
self.setupUi(self)
# -- Barra lateral esconde esconde --
# instala esse EventFilter
qApp.installEventFilter(self)
QtCore.QTimer.singleShot(0, self.frame.hide)
def eventFilter(self, source, event):
# do not hide frame when frame shown
if qApp.activePopupWidget() is None:
if event.type() == QtCore.QEvent.MouseMove:
if self.frame.isHidden():
self.frame.show()
rect = self.geometry()
# set mouse-sensitive zone
rect.setHeight(25)
if rect.contains(event.globalPos()):
self.frame.show()
else:
rect = QtCore.QRect(
self.frame.mapToGlobal(QtCore.QPoint(0, 0)),
self.frame.size())
if not rect.contains(event.globalPos()):
self.frame.hide()
elif event.type() == QtCore.QEvent.Leave and source is self:
self.frame.hide()
return QMainWindow.eventFilter(self, source, event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = TelaPrincipal()
main.show()
sys.exit(app.exec())
你有什么建议??
花了一点时间阅读文档。我发现的最简单的方法是:
在 class init 中我安装了一个过滤器,然后我覆盖了 eventFilter 方法。
class MainScreen(QMainWindow, QDialog, Ui_TelaPrincipal):
def __init__(self, parent=None):
super(MainScreen, self).__init__(parent)
QDialog.__init__(self, parent)
QMainWindow.__init__(self, parent)
Ui_MainScreen.__init__(self)
self.setupUi(self)
# ---- side bar ---- #
# installs a filter event
qApp.installEventFilter(self)
# hide the bar
QTimer.singleShot(0, self.plano_barra.hide)
self.plano_central.setMouseTracking(1)
self.plano_botao_barra.setMouseTracking(1)
self.setMouseTracking(1)
self.plano_principal.setMouseTracking(1)
def eventFilter(self, source, event):
if event.type() == QEvent.MouseMove:
if source == self.plano_botao_barra:
print("i am over the button")
self.plano_barra.show()
if source == self.plano_central:
print("i am at the main plan")
self.plano_barra.hide()
return QMainWindow.eventFilter(self, source, event)
我一直在尝试构建一个具有动态侧边栏的应用程序。我正在使用 qtdesigner 和 pyqt5。我尝试了两种方式:
1) 使用悬停样式表。但是侧边栏(框架)上有按钮。碰巧当我看到栏时,我只能看到鼠标处于打开状态的按钮。
样式表代码:
QFrame {
background-color: rgba(255, 151, 231, 0);
}
QFrame:hover {
background-color:rgba(255, 151, 231, 0.45)
}
QPushButton {
color: rgba(0, 0, 0, 0);
background-color: rgba(255, 151, 231, 0);
}
QPushButton:hover {
background-color:rgba(255, 151, 231, 0.45);
}
输出:(鼠标在按钮上)
我知道为什么会这样,但我不知道怎么解决。
2) 使用事件
使用事件我可以达到我想要的,但我不确定我是否做对了。
class TelaPrincipal(QDialog, QMainWindow, Ui_Form):
def __init__(self, parent=None):
super(TelaPrincipal, self).__init__(parent)
QDialog.__init__(self, parent)
Ui_Form.__init__(self)
self.setupUi(self)
# -- Barra lateral esconde esconde --
# instala esse EventFilter
qApp.installEventFilter(self)
QtCore.QTimer.singleShot(0, self.frame.hide)
def eventFilter(self, source, event):
# do not hide frame when frame shown
if qApp.activePopupWidget() is None:
if event.type() == QtCore.QEvent.MouseMove:
if self.frame.isHidden():
self.frame.show()
rect = self.geometry()
# set mouse-sensitive zone
rect.setHeight(25)
if rect.contains(event.globalPos()):
self.frame.show()
else:
rect = QtCore.QRect(
self.frame.mapToGlobal(QtCore.QPoint(0, 0)),
self.frame.size())
if not rect.contains(event.globalPos()):
self.frame.hide()
elif event.type() == QtCore.QEvent.Leave and source is self:
self.frame.hide()
return QMainWindow.eventFilter(self, source, event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = TelaPrincipal()
main.show()
sys.exit(app.exec())
你有什么建议??
花了一点时间阅读文档。我发现的最简单的方法是:
在 class init 中我安装了一个过滤器,然后我覆盖了 eventFilter 方法。
class MainScreen(QMainWindow, QDialog, Ui_TelaPrincipal):
def __init__(self, parent=None):
super(MainScreen, self).__init__(parent)
QDialog.__init__(self, parent)
QMainWindow.__init__(self, parent)
Ui_MainScreen.__init__(self)
self.setupUi(self)
# ---- side bar ---- #
# installs a filter event
qApp.installEventFilter(self)
# hide the bar
QTimer.singleShot(0, self.plano_barra.hide)
self.plano_central.setMouseTracking(1)
self.plano_botao_barra.setMouseTracking(1)
self.setMouseTracking(1)
self.plano_principal.setMouseTracking(1)
def eventFilter(self, source, event):
if event.type() == QEvent.MouseMove:
if source == self.plano_botao_barra:
print("i am over the button")
self.plano_barra.show()
if source == self.plano_central:
print("i am at the main plan")
self.plano_barra.hide()
return QMainWindow.eventFilter(self, source, event)