python - pyqt 和 VTK:将滑块连接到 vtk 对象的问题
问题描述
我正在处理一些问题,在 PyQt5 中使用 vtk。问题是我有一个具有初始半径值的 vtk 球体和一些滑块连接到球体 dans QLCD Numbers。实际上,我想要的是当用户滑动更改值时,首先将其中一个滑块设置为 128,该值将显示在 QLCDNumber 中,并且将采用滑块的当前值来更改半径VTK 球体。
这是我的代码:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QSlider, QLCDNumber
from PyQt5.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,
QMenu, QPushButton, QRadioButton, QVBoxLayout, QWidget, QSlider,QLineEdit,QLabel)
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import *
import vtk
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt5 import Qt
def window():
source = vtk.vtkSphereSource()
source.SetCenter(0, 0, 0)
source.SetRadius(5.0)
app = QApplication(sys.argv)
win = QWidget()
Display_1 = QLCDNumber(3)
Display_2 = QLCDNumber(3)
Display_3 = QLCDNumber(3)
Display_1.setSegmentStyle(QLCDNumber.Flat)
Display_2.setSegmentStyle(QLCDNumber.Flat)
Display_3.setSegmentStyle(QLCDNumber.Flat)
Display_1.display(128)
Display_2.display(128)
Display_3.display(128)
Slider_1 = QSlider(QtCore.Qt.Horizontal)
Slider_1.setMinimum(0)
Slider_1.setMaximum(255)
Slider_1.setValue(128)
Slider_1.valueChanged.connect(Display_1.display)
Slider_1.valueChanged.connect(changevalue(Slider_1,source))
Slider_2 = QSlider(QtCore.Qt.Horizontal)
Slider_2.setMinimum(0)
Slider_2.setMaximum(255)
Slider_2.setValue(128)
Slider_2.valueChanged.connect(Display_2.display)
Slider_3 = QSlider(QtCore.Qt.Horizontal)
Slider_3.setMinimum(0)
Slider_3.setMaximum(255)
Slider_3.setValue(128)
Slider_3.valueChanged.connect(Display_3.display)
label_1 = QLabel("Label_1")
label_1.setAlignment(QtCore.Qt.AlignCenter)
label_2 = QLabel("Label_2")
label_2.setAlignment(QtCore.Qt.AlignCenter)
label_3 = QLabel("Label_3")
label_3.setAlignment(QtCore.Qt.AlignCenter)
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(label_1)
vbox.addWidget(Display_1)
vbox.addWidget(Slider_1)
vbox.addWidget(label_2)
vbox.addWidget(Display_2)
vbox.addWidget(Slider_2)
vbox.addWidget(label_3)
vbox.addWidget(Display_3)
vbox.addWidget(Slider_3)
vbox.addStretch()
hbox = QtWidgets.QHBoxLayout()
frame = QtWidgets.QFrame()
frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
frame.setFrameShape(QtWidgets.QFrame.StyledPanel) # Application de la forme
frame.setFrameShadow(QtWidgets.QFrame.Raised) # application d'une ombre
frame.setObjectName("frame") # Appellation du cadre
#b3 = QtWidgets.QPushButton("Button3")
#b4 = QtWidgets.QPushButton("Button4")
hbox.addWidget(frame)
hbox.addStretch()
#hbox.addWidget(b4)
vbox.addStretch()
hbox.addLayout(vbox)
win.setLayout(hbox)
vtkWidget = QVTKRenderWindowInteractor(frame)
vl = Qt.QVBoxLayout()
vl.addWidget(vtkWidget)
ren = vtk.vtkRenderer()
vtkWidget.GetRenderWindow().AddRenderer(ren)
iren = vtkWidget.GetRenderWindow().GetInteractor()
# Create a mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(source.GetOutputPort())
# Create an actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
ren.AddActor(actor)
ren.ResetCamera()
frame.setLayout(vl)
#setCentralWidget(self.frame)
#show()
iren.Initialize()
iren.Start()
win.setWindowTitle("PyQt")
win.resize(743, 430)
win.show()
sys.exit(app.exec_())
def changevalue(slider,source):
value = slider.value()
source.SetRadius(int(value))
if __name__ == '__main__':
window()
当我尝试使用代码时,python 向我返回以下错误:“文件“window.py”,第 38 行,在窗口 Slider_1.valueChanged.connect(changevalue(Slider_1,source)) 类型错误:参数 1 具有意外类型 'NoneType '"
任何想法 ?
提前致谢
解决方案
connect
PyQt 中的方法需要一个函数对象。相反,您正在调用一个函数:
changevalue(Slider_1,source)
该函数changevalue
不返回任何内容。换句话说,它返回None
.
因此,当您拨打电话时:
Slider_1.valueChanged.connect(changevalue(Slider_1,source))
你真正做的是connect
用None
作为参数调用,因为这是你的函数调用changevalue
返回的内容。相反,您需要将 function 传递给它changevalue
,但是由于您需要使用参数调用该函数,因此您需要执行以下操作:
...
Slider_1 = QSlider(QtCore.Qt.Horizontal)
Slider_1.setMinimum(0)
Slider_1.setMaximum(255)
Slider_1.setValue(128)
def handler():
changevalue(Slider_1, source)
Slider_1.valueChanged.connect(Display_1.display)
Slider_1.valueChanged.connect(handler)
...
我用这个修改运行了你的代码并显示了球体。但是,还有另一个问题,那就是当您移动滑块时,您的球体不会更新。为了让 VTK 渲染器更新,您需要弄清楚如何调用iren.reinitialize()
您的changevalue
处理程序,或者达到此效果。重新初始化调用将导致渲染窗口更新以响应滑块的移动。
推荐阅读
- java - 即使使用更新的 gradle 文件,也无法解析符号“firebase”
- visual-studio-code - 如何在 VS Code 中为多个主题自定义 textMateRules?
- jbpm - 部署 jbpm 应用程序时命名查询出错
- javascript - 尝试在引导弹出窗口中添加其他表单复选框
- excel - Excel:计算两个匹配单元格的实例
- java - 根据其他bean有条件地选择bean
- php - 是否可以继承父范围成员属性并将其分配给“use”语句中的内部变量?
- c# - 如何在 404 页面上保持 URL 相同但显示自定义视图
- php - 如何在 Laravel/Passport 中覆盖 `issueToken` 方法
- python - Keras 模型误解了输入数据的形状