The last introduced how to display VTK graphics in QT's Widget, but in fact, there is still a problem that there is no solution, which is when the left mouse button drags the graphic to rotate, the graphics will have zoom or inexplicable movement, and The original method also uses the comparative underlying Winevent () function to pick up the mouse event from all messages. One of this package and its unrestrained, the two Winevent () functions can only be used under the Windows platform, This will lose cross-platform.
Just in the modification of the default mouse operation (under VTK, named interaction: interactorsty), find a relatively simple solution, perfectly solving the above problems.
First, I used VtkinteractorsTyletRackballballCamera to replace the default interaction in the interactive (vtkinteractor). What is the difference between the two interactions, I am also difficult to use language description, in short, this seems to be more in line with my usage habits. Replacing the code of the default interaction method of vtkinteractor is:
MINTERACTORSTYLE = vtkinteractorstyletRackballballCamera :: new (); minteractor-> setInteractorstyle (minteractorstyle);
Simple, the vtkinteractor is called the interactive, its role can be seen as all window messages of VTKWindow, then processed, vtkwindow itself is only responsible for display, this is actually dividing the display and message processing function of the ordinary WINDOWS window into two A class is managed, and the specific content of this is the next time you have the opportunity to slowly explain.
Just said that Vtkinteractor, it is actually just an agent class, which is responsible for getting a mouse and keyboard message, then according to these messages, the graph on the form reflects, this is determined by a member of the Vtkinteractorstyle. This class has a variety of different derivatives (implementation), so as long as the different derived objects can be easily changed, this is what the above minteractor-> setInteractorStyle () function does.
After finishing the above code, I found that my program did not update the mouse operation as expected. What is going on? It turns out that the vkthandleMessage2 () function I use does not use any interactor, but it handles the message. It seems that the programs written by mfcsample in the same time it used to use extremely informal methods.
Carefully view the Help of VTK, inadvertently find vtkinteractorstyle: ONLEFTBUTTONDOWN (); OnrightButtondown (); Waiting for several public functions, it seems to be used, so I will have a modification of the code, cover the qt mousepress (), MouseMoveEvent (), MouseReleaseEvent () and other functions, then add the mouse operation function in Interactorstyle, ok, run the program. . . . He is still not reflected. . At this time, the advantages of OpenSource are reflected, and the document is not good. I can see Source directly. I will take ONLTBUTTONDOWN () to see it. It turns out that this is going to get the location of the mouse, but there is no yourself. Take this value, but based on the intector's getEventPosition () function, the good office, call the minteractor-> setEventPosition () function before various MOUSE times, tell it the location of the current mouse It is OK, and then try again, you can use the mouse to operate. But with the left mouse button, the left and right moves, the graph is rotated to the left, and the moving direction of the graph is just the opposite. What is going on? A further watching the document, there is still a function name: setEventPositionflipy (), it seems that the developer knows that I will meet this problem, change it to a try, oh, it is completely normal! Later, I wanted to understand that the origin of the mouse under Windows is the upper left corner of the screen, and in the OpenGL graphics system, the origin is the upper left corner, so of course you need to reverse the Y axis. Finally, put the relevant code:
Void EnstmapWidget :: MousePressevent (QMouseEvent * e) {minteractor-> setEventPositionFlipy (e-> x (), e-> y ()); switch (e-> button ()) {CASE Qt :: leftbutton: minteractorstyle-> ONLEFTBUTTONDOWN (); Break; Case Qt :: RightButton: minteracty -> OnrightButtondown (); Break; Case Qt :: MidButton: minteractorsty-> onmiddlebuttondown () (); Break;}}
Void EnstmapWidget :: MouseMoveEvent (QMouseEvent * E) {minteractor-> setEventPositionFlipy (e-> x (), e-> y ()); minteractorsty-> onMouseMove ();}
Void EnstmapWidget :: mouseeeleaseEvent (qmouseeevent * e) {minteractor-> setEventPositionFlipy (e-> x (), e-> y ()); switch (e-> button ()) {copy qt :: leftbutton: minteractorstyle-> ONLAK; CASE QT :: RightButton: minteractorsty-> online; case}; bundlebuttonup (); break;}} additional The main program interface, look at the effect: