pythonpyqtvtkqvtkwidgetvedo

Vedo Plotter in Qt - Mouse Click Event not registering at the correct position


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" attributes 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.

def __init__(self,size):
    super(MainWindow, self).__init__()

    # load the components defined in th xml file
    loadUi("viewer_gui.ui", self)
    self.screenSize = size

    # Connections for all elements in Mainwindow
    self.pushButton_inputfile.clicked.connect(self.getFilePath)
    self.pushButton_clearSelection.clicked.connect(self.clearScreen)
    self.action_selectVertex.toggled.connect(self.actionSelection_state_changed)
    self.action_selectActor.toggled.connect(self.actionSelection_state_changed)

    # Set up VTK widget
    self.vtkWidget = QVTKRenderWindowInteractor()
    self.splitter_viewer.addWidget(self.vtkWidget)

    # ipy console
    self.ipyConsole = QIPythonWidget(customBanner="Welcome to the embedded ipython console\n")
    self.splitter_viewer.addWidget(self.ipyConsole)
    self.ipyConsole.pushVariables({"foo":43, "print_process_id":print_process_id, "ipy":self.ipyConsole, "self":self})
    self.ipyConsole.printText("The variable 'foo' and the method 'print_process_id()' are available.\
        Use the 'whos' command for information.\n\nTo push variables run this before starting the UI:\
            \n ipyConsole.pushVariables({\"foo\":43,\"print_process_id\":print_process_id})")

    # Create renderer and add the vedo objects and callbacks
    self.plt = Plotter(qtWidget=self.vtkWidget,bg='DarkSlateBlue',bg2='MidnightBlue',screensize=(1792,1120))
    self.id1 = self.plt.addCallback("mouse click", self.onMouseClick)
    self.id2 = self.plt.addCallback("key press",   self.onKeypress)
    self.plt.show()                  # <--- show the vedo rendering

def onMouseClick(self, event):
    if(self.action_selectActor.isChecked()):
        self.selectActor(event)
    elif(self.action_selectVertex.isChecked()):
        self.selectVertex(event)

def selectActor(self,event):
    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])
    # adding a silhouette might cause some lags
    # self.plt += event.actor.silhouette().lineWidth(2).c('red')
    #an alternative solution
    self.actorSelection = event.actor.clone()
    self.actorSelection.c('red')
    self.plt += self.actorSelection

def selectVertex(self,event):
    if(not event.isPoints):
        return
    # print(arr[event.actor.closestPoint(event.picked3d, returnPointId=True)])
    printc("You have clicked your mouse button. Event info:\n", event, c='y')
    printc("Left button pressed on 3d: ", [event.picked3d])
    printc("Left button pressed on 2d: ", [event.picked2d])
    p = pointcloud.Point(pos=(event.picked3d[0],event.picked3d[1],event.picked3d[2]),r=12,c='red',alpha=0.5)
    self.vertexSelections.append(p)        
    self.plt += p

Running the following lines:

app = QApplication(sys.argv)
screen = app.primaryScreen()
print('Screen: %s' % screen.name())
size = screen.size()
print('Size: %d x %d' % (size.width(), size.height()))

outputted:

Screen: Color LCD
Size: 1792 x 1120

Solution

  • This turns out to be an upstream bug in vtk, unrelated to vedo. After downgrading VTK to version 8.1.2 and Python to 3.7, the clicking issue disappeared when running the program on my laptop. Other people also encountered the same problem, and here is an error report on vtk’s website that describes how vtkPropPicker is now returning the wrong world coordinates.