Closed danieljiang520 closed 2 years ago
Sorry I cannot reproduce the issue. This seems to work as expected:
import sys
from PyQt5 import Qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vedo import Plotter, Cone, printc, Point
class MainWindow(Qt.QMainWindow):
def __init__(self, size, parent=None):
self.actorSelection = None
self.vertexSelections = []
self.silu = None
Qt.QMainWindow.__init__(self, parent)
self.frame = Qt.QFrame()
self.layout = Qt.QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
# Create renderer and add the vedo objects and callbacks
self.plt = Plotter(qtWidget=self.vtkWidget)
self.id1 = self.plt.addCallback("mouse click", self.onMouseClick)
self.id2 = self.plt.addCallback("key press", self.onKeypress)
self.plt += Cone().rotateX(20)
self.plt.show() # <--- show the vedo rendering
# Set-up the rest of the Qt window
button = Qt.QPushButton("My Button makes the cone red")
button.setToolTip('This is an example button')
button.clicked.connect(self.onClick)
self.layout.addWidget(self.vtkWidget)
self.layout.addWidget(button)
self.frame.setLayout(self.layout)
self.setCentralWidget(self.frame)
self.show() # <--- show the Qt Window
def onMouseClick(self, event):
printc("..vedo calling onMouseClick")
if not event.actor:
return
#printc("You have clicked your mouse button. Event info:\n", event, c='y')
printc("Left button pressed on", event.picked3d)
self.silu = event.actor.silhouette().lineWidth(5).c('purple5')
pt = Point(event.picked3d).c('black').ps(12)
self.vertexSelections.append(pt)
self.plt.remove(self.silu).add([self.silu, pt])
def onKeypress(self, evt):
printc("You have pressed key:", evt.keyPressed, c='b')
@Qt.pyqtSlot()
def onClick(self):
printc(".. Qt calling onClick")
self.plt.actors[0].color('red').rotateZ(40)
self.plt.interactor.Render()
def onClose(self):
#Disable the interactor before closing to prevent it
#from trying to act on already deleted items
printc("..calling onClose")
self.vtkWidget.close()
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
screen = app.primaryScreen()
size = screen.size()
print('Screen: %s' % screen.name())
print('Size: %d x %d' % (size.width(), size.height()))
window = MainWindow(size)
app.aboutToQuit.connect(window.onClose) # <-- connect the onClose event
app.exec_()
Hi Daniel, thanks for reporting, let's try this exercise:
pip install -U git+https://github.com/marcomusy/vedo.git
then
import sys
from PyQt5 import Qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vedo import Plotter, Cone, printc, Point
from vedo.cli import exe_info
class MainWindow(Qt.QMainWindow):
def __init__(self, size, parent=None):
Qt.QMainWindow.__init__(self, parent)
self.frame = Qt.QFrame()
self.layout = Qt.QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
# Create renderer and add the vedo objects and callbacks
self.plt = Plotter(qtWidget=self.vtkWidget, pos=(0,0))
self.id1 = self.plt.addCallback("mouse click", self.onMouseClick)
self.plt += Cone().rotateX(20)
self.plt.show() # <--- show the vedo rendering
# Set-up the rest of the Qt window
self.layout.addWidget(self.vtkWidget)
self.frame.setLayout(self.layout)
self.setCentralWidget(self.frame)
self.show() # <--- show the Qt Window
def onMouseClick(self, event):
printc("Left button pressed on 2D", event.picked2d, c='y')
if not event.actor:
return
printc("Left button pressed on 3D", event.picked3d, c='g')
pt = Point(event.picked3d).c('pink').ps(12)
self.plt.add(pt)
if __name__ == "__main__":
exe_info([]) # will dump some info about the system
app = Qt.QApplication(sys.argv)
screen = app.primaryScreen()
size = screen.size()
print('Screen: %s' % screen.name())
print('Size: %d x %d' % (size.width(), size.height()))
window = MainWindow(size)
app.exec_()
now click the canvas corners , starting from the bottom-left anticlockwise, then the tip of the cone:
you should get something like this output:
Hi Marco, here is my output after running the test. I did not resize the window but it seems like the positions are twice as far as what they are supposed to be.
Oh I can finally reproduce the issue on my mac! I'm investigating it..
ok... this seems to be an upstream bug in vtk, unrelated to vedo: https://discourse.vtk.org/t/vtkproppicker-not-working-in-osx-and-qt/8057 i'm afraid we need to wait for their input on this!
Thank you for looking into this bug. Hopefully, vtk will respond soon.
They seem to recognize the problem but I guess it will take time to solve... maybe you can try VTK 8.1 if you have the possibility to use that version.
After downgrading VTK to version 8.1.2 and Python to 3.7, the clicking issue disappeared when running the program on my laptop. Thank you for the help! I will keep an eye on new releases from vtk.
Hi, I'm very new to vedo (thanks for making such a great library!), but I've come across this issue with vtk before. Based on the comments in a previous issue related to this problem, it sounds like there is no plan to fix it as vtkmodules/qt/QVTKRenderWindowInteractor.py
is not maintained by the core VTK devs. But I'm sure they'd be open to someone submitting a fix.
There used to be the opposite problem whereby coordinates would be scaled by a factor of 0.5, so a fix was made for this in QVTKRenderWindowInteractor
. However, this fix is no longer necessary (possibly due to changes made in qt), and so the original fix is now actually a bug. The fix introduced a method _getPixelRatio
, which determines the factor by which coordinates needed to be scaled to fix the previous bug (and on Mac retina displays this was a factor of two). As no scaling needs to be applied, I've been using a hacky fix to make this method always return a value of 1:
interactor = QVTKRenderWindowInteractor()
interactor._getPixelRatio = lambda _: 1
This is a great piece of information! Thanks for letting us know!
I have tried several different things about the mouse clicks not registering correctly in my Qt mainwindow. When using only my QHD monitor, the program worked just fine (video). However, when using my laptop (zoomed in at 1792 x 1120) as the only display, the mouse clicks seemed to have a varying up-right offset and register more accurately near the bottom left corner of the widget (video). I am suspicious that the screen resolution of the display might cause a problem for vedo.
The mouse event is a vedo plotter event. Changing the "screensize", "size", "pos" attribute of the plotter did not fix the issue.
I looked up some examples provided by vedo, specifically mousehover.py and qt_window1.py. The mousehover example worked fine on my laptop. However, adding a clicking event in qt_window1.py also created the same issue. Therefore, the problem most likely was caused by the qt widget.
Running the following lines:
outputted