删除 PlotWidget 后如何删除选项卡小部件中的空 space(void)?
How to remove empty space(void) in the tab widget after removing a PlotWidget?
我有一个小型仪表板应用程序,我可以在其中动态添加和删除图表。问题是,当我单击 x 按钮(杀死图形小部件)时,图形从视图中消失,但在剩余图形上方留下一个空隙(参见随附的屏幕截图)。
我在这方面几乎是一个完全的初学者,但我怀疑我没有正确处理小部件和对象的删除?
在我下面的简化代码中,我有 class dashboard_tab
,通过单击按钮我创建了一个 add_new_graph
对象,该对象创建了一个新的图形小部件 self.graphWidget = pg.PlotWidget()
。
当启动图形小部件关闭(或终止)时,我调用以下代码:
def kill_widget(self):
self.lay.removeWidget(self.graphWidget)
self.graphWidget.deleteLater()
self.graphWidget = None
这似乎以某种方式起作用,因为图形小部件从视图中消失了,但不需要的空隙却没有。
然后我的想法是也杀死 add_new_graph
对象...如果它与我的问题有任何关系...通过创建从 add_new_graph
对象返回到dashboard_tab
对象...但它无法正常工作。
所以我的问题是:
- 删除小部件后出现不需要的空白的最可能原因是什么?
- 我是否还必须删除对象才能获得正确的编码?
如有任何正确方向的建议,我们将不胜感激!
class MainWindow(QtWidgets.QWidget):
def __init__(self, parent):
super(QtWidgets.QWidget, self).__init__(parent)
self.layout = QtWidgets.QVBoxLayout(self)
self.tab_holder = QtWidgets.QTabWidget()
tab1 = dashboard_tab()
self.tab_holder.addTab(tab1, "Dashboard")
self.layout.addWidget(self.tab_holder)
class dashboard_tab(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.lay = QtWidgets.QVBoxLayout(self)
self.numGraphs = 0
addGraphBtn = QtWidgets.QToolButton()
addGraphBtn.setText(" Add Graph")
addGraphBtnMenu = QtWidgets.QMenu()
addGraphBtnMenu.addAction('Add Temp Graph', self.add_graph)
addGraphBtn.setMenu(addGraphBtnMenu)
self.lay.addWidget(addGraphBtn)
def add_graph(self):
# Create a unique graph name
self.name = ("graph" + str(self.numGraphs))
self.graph = add_new_graph(self.name)
self.lay.addWidget(self.graph)
# Up graph name index every time a new graph is created
self.numGraphs += 1
class add_new_graph(QtWidgets.QWidget):
def __init__(self, name):
super().__init__()
self.name = name
self.lay = QtWidgets.QHBoxLayout(self)
self.graphWidget = pg.PlotWidget()
self.killWidgetBtn = QtWidgets.QPushButton('')
self.killWidgetBtn.clicked.connect(self.kill_widget)
self.lay.addWidget(self.killWidgetBtn)
self.lay.addWidget(self.graphWidget)
def kill_widget(self):
self.lay.removeWidget(self.killWidgetBtn)
self.killWidgetBtn.deleteLater()
self.killWidgetBtn = None
self.lay.removeWidget(self.graphWidget)
self.graphWidget.deleteLater()
self.graphWidget = None
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
仪表板应用程序屏幕截图
发生的情况是您只删除了子窗口小部件(图表和按钮),而不是您添加到布局中的容器窗口小部件。
即使在删除这些对象之后,容器的布局也有一个最小尺寸 contents margins(取决于操作系统和当前样式,它们通常在 5 到 10 像素之间),这就是 "void"你可以看到。
您可以删除容器而不是删除子窗口小部件。
class add_new_graph(QtWidgets.QWidget):
def __init__(self, name):
# ...
self.killWidgetBtn.clicked.connect(<b>self.deleteLater</b>)
无论如何,您可能希望在删除此类小部件时收到警告,因此我建议让家长有责任这样做:
class dashboard_tab(QtWidgets.QWidget):
# ...
def add_graph(self):
# ...
graph = add_new_graph(self.name)
graph.deleteRequested.connect(self.deleteGraph)
def deleteGraph(self, graph):
# some warning message box, maybe?
if QtWidgets.QMessageBox.warning(self, 'Close?',
'Delete the graph?',
QtWidgets.QMessageBox.Ok|QtWidgets.QMessageBox.Cancel
) != QtWidgets.QMessageBox.Ok:
return
graph.deleteLater()
class add_new_graph(QtWidgets.QWidget):
deleteRequested = QtCore.pyqtSignal(object)
def __init__(self, name):
# ...
self.killWidgetBtn.clicked.connect(
lambda: <b>self.deleteRequested.emit(self)</b>)
一个建议,如果可以的话:对 类 使用大写名称(这样它们可以很容易地与函数区分开来),并且不要使用 "action descriptions" 作为它们的名称:类 通常不会 "do" 事情本身,他们的方法会。
我有一个小型仪表板应用程序,我可以在其中动态添加和删除图表。问题是,当我单击 x 按钮(杀死图形小部件)时,图形从视图中消失,但在剩余图形上方留下一个空隙(参见随附的屏幕截图)。
我在这方面几乎是一个完全的初学者,但我怀疑我没有正确处理小部件和对象的删除?
在我下面的简化代码中,我有 class dashboard_tab
,通过单击按钮我创建了一个 add_new_graph
对象,该对象创建了一个新的图形小部件 self.graphWidget = pg.PlotWidget()
。
当启动图形小部件关闭(或终止)时,我调用以下代码:
def kill_widget(self):
self.lay.removeWidget(self.graphWidget)
self.graphWidget.deleteLater()
self.graphWidget = None
这似乎以某种方式起作用,因为图形小部件从视图中消失了,但不需要的空隙却没有。
然后我的想法是也杀死 add_new_graph
对象...如果它与我的问题有任何关系...通过创建从 add_new_graph
对象返回到dashboard_tab
对象...但它无法正常工作。
所以我的问题是:
- 删除小部件后出现不需要的空白的最可能原因是什么?
- 我是否还必须删除对象才能获得正确的编码?
如有任何正确方向的建议,我们将不胜感激!
class MainWindow(QtWidgets.QWidget):
def __init__(self, parent):
super(QtWidgets.QWidget, self).__init__(parent)
self.layout = QtWidgets.QVBoxLayout(self)
self.tab_holder = QtWidgets.QTabWidget()
tab1 = dashboard_tab()
self.tab_holder.addTab(tab1, "Dashboard")
self.layout.addWidget(self.tab_holder)
class dashboard_tab(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.lay = QtWidgets.QVBoxLayout(self)
self.numGraphs = 0
addGraphBtn = QtWidgets.QToolButton()
addGraphBtn.setText(" Add Graph")
addGraphBtnMenu = QtWidgets.QMenu()
addGraphBtnMenu.addAction('Add Temp Graph', self.add_graph)
addGraphBtn.setMenu(addGraphBtnMenu)
self.lay.addWidget(addGraphBtn)
def add_graph(self):
# Create a unique graph name
self.name = ("graph" + str(self.numGraphs))
self.graph = add_new_graph(self.name)
self.lay.addWidget(self.graph)
# Up graph name index every time a new graph is created
self.numGraphs += 1
class add_new_graph(QtWidgets.QWidget):
def __init__(self, name):
super().__init__()
self.name = name
self.lay = QtWidgets.QHBoxLayout(self)
self.graphWidget = pg.PlotWidget()
self.killWidgetBtn = QtWidgets.QPushButton('')
self.killWidgetBtn.clicked.connect(self.kill_widget)
self.lay.addWidget(self.killWidgetBtn)
self.lay.addWidget(self.graphWidget)
def kill_widget(self):
self.lay.removeWidget(self.killWidgetBtn)
self.killWidgetBtn.deleteLater()
self.killWidgetBtn = None
self.lay.removeWidget(self.graphWidget)
self.graphWidget.deleteLater()
self.graphWidget = None
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
仪表板应用程序屏幕截图
发生的情况是您只删除了子窗口小部件(图表和按钮),而不是您添加到布局中的容器窗口小部件。
即使在删除这些对象之后,容器的布局也有一个最小尺寸 contents margins(取决于操作系统和当前样式,它们通常在 5 到 10 像素之间),这就是 "void"你可以看到。
您可以删除容器而不是删除子窗口小部件。
class add_new_graph(QtWidgets.QWidget):
def __init__(self, name):
# ...
self.killWidgetBtn.clicked.connect(<b>self.deleteLater</b>)
无论如何,您可能希望在删除此类小部件时收到警告,因此我建议让家长有责任这样做:
class dashboard_tab(QtWidgets.QWidget):
# ...
def add_graph(self):
# ...
graph = add_new_graph(self.name)
graph.deleteRequested.connect(self.deleteGraph)
def deleteGraph(self, graph):
# some warning message box, maybe?
if QtWidgets.QMessageBox.warning(self, 'Close?',
'Delete the graph?',
QtWidgets.QMessageBox.Ok|QtWidgets.QMessageBox.Cancel
) != QtWidgets.QMessageBox.Ok:
return
graph.deleteLater()
class add_new_graph(QtWidgets.QWidget):
deleteRequested = QtCore.pyqtSignal(object)
def __init__(self, name):
# ...
self.killWidgetBtn.clicked.connect(
lambda: <b>self.deleteRequested.emit(self)</b>)
一个建议,如果可以的话:对 类 使用大写名称(这样它们可以很容易地与函数区分开来),并且不要使用 "action descriptions" 作为它们的名称:类 通常不会 "do" 事情本身,他们的方法会。