【问题标题】:How to correctly embed a Vispy canvas on a PySide2 GUI?如何在 PySide2 GUI 上正确嵌入 Vispy 画布?
【发布时间】:2022-01-02 17:49:06
【问题描述】:

我正在尝试使用 Vispy 和 PySide2 创建一个 GUI。我对这些图书馆很陌生。 当我尝试为 Vispy 的画布设置对齐方式时遇到问题。

无论我尝试什么对齐标志,我都会收到此错误消息。 我怀疑 Vispy 画布嵌入不正确。 有人可以帮忙吗?

   central_layout.addWidget(canvas       , 2,0,1,2 , QtCore.Qt.AlignCenter )

TypeError: 'PySide2.QtWidgets.QGridLayout.addWidget' called with wrong argument types:
 PySide2.QtWidgets.QGridLayout.addWidget(SceneCanvas, int, int, int, int, AlignmentFlag)
Supported signatures:
 PySide2.QtWidgets.QGridLayout.addWidget(PySide2.QtWidgets.QWidget, int, int, PySide2.QtCore.Qt.Alignment = Default(Qt.Alignment))
 PySide2.QtWidgets.QGridLayout.addWidget(PySide2.QtWidgets.QWidget, int, int, int, int, PySide2.QtCore.Qt.Alignment = Default(Qt.Alignment))
 PySide2.QtWidgets.QGridLayout.addWidget(PySide2.QtWidgets.QWidget)

我在 Spyder 上运行 Python 3.8.1、vispy 0.9.3 和 PySide2 5.13.2。

import matplotlib
matplotlib.use('Agg')
import sys
sys.path.append("../../../")


import vispy
import pyglet
vispy.app.use_app('pyglet')
from vispy import color, scene, app

from PySide2.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout, QComboBox, QHBoxLayout, QPushButton, QCheckBox, QLineEdit, QLabel
from PySide2 import QtCore



if not QApplication.instance():
    app = QApplication(sys.argv)
else:
    app = QApplication.instance()

mw  = QMainWindow()
mw.resize(1900,1000)

# build canvas
canvas = scene.SceneCanvas(keys='interactive', show=False)
# canvas = vispy.app.canvas.Canvas(keys='interactive', show=False)

central_layout = QGridLayout()
central_widget = QWidget()
central_widget.setLayout(central_layout)

mw.setCentralWidget(central_widget)
mw.setWindowTitle('Driving Test (2D/3D)')

configuration_layout      = QHBoxLayout()
debug_layout              = QHBoxLayout()

cmap_attribute            = QComboBox()
cmap_type                 = QComboBox()
cycle_label               = QLabel('Cycle :')
debug_mode_checkbox       = QCheckBox('Debug Mode')
input_cycle               = QLineEdit()
go_to_specific_cycle_btn  = QPushButton('GO')
next_cycle_btn            = QPushButton('Next Cycle')
previous_cycle_btn        = QPushButton('Previous Cycle')
attribute_selected_info   = QLabel()

input_cycle.setPlaceholderText('Enter a spécific cycle and click on (GO)')

input_cycle.setMaximumWidth(250)
go_to_specific_cycle_btn.setMaximumWidth(50)
debug_mode_checkbox.setMaximumWidth(100)
cycle_label.setFixedSize(80, 40)
attribute_selected_info.setFixedSize(500, 40)

cmap_attribute.addItems(['snr','power','rcs','velocity', 'range','detection_confidence','elevation'])
cmap_type.addItems(['jet','viridis'])

configuration_layout.addWidget(cmap_attribute)
configuration_layout.addWidget(cmap_type)

debug_layout.addWidget(debug_mode_checkbox)
debug_layout.addWidget(input_cycle)
debug_layout.addWidget(go_to_specific_cycle_btn)
debug_layout.addWidget(previous_cycle_btn)
debug_layout.addWidget(next_cycle_btn)
debug_layout.addWidget(cycle_label)
debug_layout.addWidget(attribute_selected_info)

central_layout.addLayout(configuration_layout , 0,0,1,2)
central_layout.addLayout(debug_layout         , 1,0,1,2)
central_layout.addWidget(canvas       , 2,0,1,2 , QtCore.Qt.AlignCenter )
top_grid = canvas.central_widget.add_grid()


mw.show()


if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QApplication.instance().exec_()
```

【问题讨论】:

  • 在您的addWidget 通话中使用canvas.native 而不是canvas。让我知道情况如何。
  • 我已经尝试过了,但它不起作用。我收到此错误消息:TypeError: 'PySide2.QtWidgets.QGridLayout.addWidget' called with wrong argument types: PySide2.QtWidgets.QGridLayout.addWidget(CanvasBackend, int, int, int, int, AlignmentFlag)
  • 所以.native 应该是QGLWidget,它是QWidget 的子类,所以应该没问题。只是为了确定您是否可以尝试删除最后一个参数(AlignCenter)并查看是否可以解决问题?
  • 还是不行。我收到相同的错误消息。
  • @djhoese 你知道这是因为我的 spyder 版本还是仅仅因为 spyder?

标签: python spyder pyside2 vispy


【解决方案1】:

如 cmets 中所述,将 vispy Canvas(或 SceneCanvas)对象添加到 GUI 框架的正确方法是将 canvas.native 添加到 GUI。 canvas.native 应该等同于 GUI 后端所期望的任何“小部件”。

您的另一个问题原来是您从 Spyder 运行并强制 vispy 后端到 pyglet。我对 pyglet 了解不多,所以我不确定是否可以使用 pyglet + pyside2,但如上所述 .native 与您选择的后端相关联,因此它一定是在将 pyglet 对象传递给 pyside2 .

您在使用 pyside2 并从 spyder 运行程序时提到的最后一个错误可能是从 spyder 中运行其他 GUI 框架之间的不兼容。至少这是我的猜测。

【讨论】:

    猜你喜欢
    • 2018-02-08
    • 2018-08-26
    • 2023-03-12
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2021-07-30
    • 2018-12-14
    • 2013-12-07
    相关资源
    最近更新 更多