Matplotlib 中的透明导航栏(或者,可以在没有栏的情况下添加导航按钮吗?)

Posted

技术标签:

【中文标题】Matplotlib 中的透明导航栏(或者,可以在没有栏的情况下添加导航按钮吗?)【英文标题】:Transparent NavigationBar in Matplotlib (or, can the Navigation buttonsbe added without a bar?) 【发布时间】:2017-10-30 06:25:12 【问题描述】:

我正在尝试使用嵌入式 matplotlib 图最大限度地利用 Qt GUI 中的空间,包括标准的 matplotlib 导航栏,以为用户提供有用的功能(缩放、保存、移动等)

不幸的是,当绘图窗口具有“宽屏”比例时,导航栏最终会占用大量空间,如下所示。所有按钮都在左侧,但 NavigationBar 也会创建一整条空白区域。

虽然我的预期应用程序是在 Qt GUI 中嵌入 matplotlib 图,但我相信这是一个普遍问题,也可能适用于默认 matplotlib ax.plot 操作显示的标准图。

可以使用这个空间吗?我尝试在这里设置文本和 mpl 小部件,但它们总是隐藏在导航栏后面。也许有一个设置可以使这个栏的颜色透明?

或者,有没有一种快速的方法可以将按钮作为小部件添加到我的图形上,因此不需要 NavigationBar。我喜欢该栏提供的样式和功能,因此不必手动重新实现每一个。

谢谢。

【问题讨论】:

【参考方案1】:

NavigationToolbar 是普通的QWidget。这意味着你可以用它做所有你也可以用其他小部件做的事情,包括

将其放入其他小部件的布局中 将其放入菜单中 改变它的布局 在 GUI 内绝对定位 等等……

这个问题有点过于宽泛,无法为所有这些提供解决方案;但是对于如何在 PyQt 中操作和定位小部件,也有足够的资源可用。

下面是绝对定位的NavigationToolbar 的示例,它(默认情况下)是透明的。工具栏位于轴的原点,如果调整图形大小,工具栏将保留在那里。

import matplotlib.pyplot as plt
from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar

class Window(QtGui.QMainWindow):
    def __init__(self, fig):
        self.qapp = QtGui.QApplication([])

        QtGui.QMainWindow.__init__(self)
        self.widget = QtGui.QWidget()
        self.setCentralWidget(self.widget)
        self.widget.setLayout(QtGui.QVBoxLayout())
        self.widget.layout().setContentsMargins(0,0,0,0)
        self.widget.layout().setSpacing(0)

        self.fig = fig
        self.canvas = FigureCanvas(self.fig)
        self.canvas.draw()
        self.canvas.mpl_connect("resize_event", self.resize)

        self.widget.layout().addWidget(self.canvas)

        self.nav = NavigationToolbar(self.canvas, self.widget, coordinates=False)
        self.nav.setMinimumWidth(300)
        self.nav.setStyleSheet("QToolBar  border: 0px ")

        self.show()
        self.qapp.exec_()

    def resize(self, event):
        # on resize reposition the navigation toolbar to (0,0) of the axes.
        x,y = self.fig.axes[0].transAxes.transform((0,0))
        figw, figh = self.fig.get_size_inches()
        ynew = figh*self.fig.dpi-y - self.nav.frameGeometry().height()
        self.nav.move(x,ynew)

# create a figure with a subplot
fig, ax = plt.subplots(figsize=(5,3))
# colorize figure and axes to make transparency obvious
fig.set_facecolor("#e9c9ef") 
ax.set_facecolor("#f7ecf9")
ax.plot([2,3,5,1], color="#ab39c1")
fig.tight_layout()

# pass the figure to the custom window
a = Window(fig)

【讨论】:

谢谢 - 这可以很好地将导航栏放置在 GUI 中更紧凑的位置。作为一个兴趣点,是否可以将它(即通常的 Qt 小部件)覆盖在其他层的顶部,理想情况下也包括一些透明度? 您为什么不尝试一下,如果它不起作用,请使用minimal reproducible example 和清晰的问题描述更新您的问题? 我仔细研究了这个,并在更新的答案中提供了一个完整的例子。 我试图实现这一点,但它的效果不如那个代码示例。非常感谢!

以上是关于Matplotlib 中的透明导航栏(或者,可以在没有栏的情况下添加导航按钮吗?)的主要内容,如果未能解决你的问题,请参考以下文章

UIView 位于半透明导航栏后面,具有实用创建的视图约束

如何让 Flutter 应用在​​ android 导航栏后面绘制并使导航栏完全透明?

如何使导航栏像 iPhone 中的照片应用一样透明并淡出

推送视图控制器中的半透明导航栏覆盖?

管理从普通导航栏到透明导航栏的过渡

如何让 React Native 应用中的 MIUI 导航栏透明?