So I have been struggling with this question for quite some time. I have tried many things, none of them seem to work.
So, I want to make a game in Qt, and one of the things I need is that player(QRectItem for now) rotate always to the mouse position. I just need to get readings of that position all the time, so not when i click or when I drag, all the time.
How can I do that?
I set
this->setMouseTracking(true);
on a class that inherits for QGraphicsView class, also I have set focus on it.
Dont know if the problem is with overriding functions(dont know which one to override) or with focus.
void Game::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
qDebug() << QCursor::pos();
}
Did this but it does not work at all.
Btw, I am noob it Qt, this is my first project.
Thanks in advance! :)
P.S.
I have really done research, but if I have somehow missed topic with same or similar question that can solve this problem, just paste it and accept my apologies. :)
EDITED
You can install an event filter on your QApplication object, examine the received events for mouse movement events, convert the resulting position into your scene, and then use it to orient your rectangle.
Look at QObject::installEventFilter. Event filters are pretty easy to use. When a mouse event is received by an object, its coordinates are in that object's coordinate space, so you'll need to convert from that to your graphics scene coordinates. There will probably be several conversions to get that because you'll need to map the received position to your QGraphicsView using mapTo and then map the result of that to your scene using QGraphicsView::mapToScene.
This should get you pretty close. Let me know if you need more help.
Related
I've been looking through the SFML documentation for making clickable sprites, but so far I haven't found anything.
Do you guys think you could help me out?
There is nothing like sf::ClickableSprite in SFML so far, and probably there will never be. (Current list of classes in SFML)
However, you can obtain this behavior with the sf::Sprite object and the events. The idea is simple - as soon as you get the sf::Mouse::isButtonPressed(sf::Mouse::Left) event, check if the mouse is in the sprite. If it is, perform the action. You can perform another action (maybe undo) when button is released.
There is sf::Sprite::getGlobalBounds() function which returns you the position and the dimensions of the sprite. There's also sf::Mouse::getPosition() function, which returns the current position of the mouse. You can use sprite.getGlobalBounds().contains(mousePos) to check whether the mouse is in the sprite.
If you're using views, you'll need to add the view's position to sf::Mouse::getPosition(window), since it gets the mouse position relative to window coordinates.
(thanks to Chaosed0 for additional notes.)
I am working on a qt-vtk project. We have a line drawing function. where straight lines are created between two mouse click position. But once actor is created it is not visible. I was calling render function just after adding the actor. But it didn't work. But if i do camera->resetview() lines become visible , but entire perspective changes. Where am i doing wrong ?
thanks
Rwik
This may not be relevant to you, but I had this exact same problem (in ActiViz [managed VTK]) and wrangled with it for a week, so I hope this helps someone out there. It turned out to be a problem with the location of the lines we wanted to draw on the canvas; they were too far away from the camera (on the Z axis) to be visible.
For us, we were trying to draw a cross on the viewing area wherever the user clicked. The data points were there, as were the actors and whatnot, but they would only be visible in the scene if you called resetCamera() and thusly changed the camera's configuration.
Initially, I blamed the custom interactor that we had to add to cirvumvent the default interactor's swallowing of MouseUp events (intended behavior). Investigation revealed that this seemed unlikely.
After this I shifted the blame onto the camera under the suspicion that perhaps the reset call was making a call to some kind of update method which I wasn't aware of. I called resetCamera() and then reverted the camera values to what they were initially.
When this was successfully done, it eventuated that the crosses would appear when the camera zoomed out and then disappear again as soon as it was set back, and it was at this point I realized that it was something to do with the scene.
At this point, I checked the methods we were using to retrieve the mouse location in 3D and realized that the z value was enormous and it was placing the points too far away as a byproduct of VTK's methods to convert 2D locations on the control to 3D locations in the scene and vice versa.
So after all that, a very mundane and avoidable mistake that originated from the methods renderer.DisplayToWorld() and WorldToDisplay().
This might not be everyone's problem, but I hope I've spared someone a week of fiddling around with VTK.
I think that's a bit hard to help, without see the code, but have you tried using
ui->qvtkwidget->update();
, where ui is the instance of your class derived from QMainWindow?
I'm developing an application with C++ and GTK3 but I'm stucked. I've created a visual application with glade which has three columns and one of them, the middle one, is a DrawingArea. In that DrawingArea I want to draw some circles at the point I want to after pressing a button and have different mouse events on that circles (like drag and drop, double click, right click...). I've made the first thing (draw a circle after pressing a button) following the official documentation, but the problem is that I don't know how to do the mouse events, but I thought about it and I have some different solutions (I don't know if they are the bests solutions or maybe there are better):
I think the best way is to create a signal to the cairomm context, but I didn't see anything to do that. Maybe the way would be to create a cairo surface or something like that.
Every time I click to create a circle, I would have to create a gtk widget in which I can handle mouse events. The problem here is that the widget needs to have circular shape and need to be drawable. Is it possible to create a circular DrawingArea? It could be the best. I saw the way to create custom widgets here.
Use goocanvasmm. The problem here is that goocanvasmm has a little documentation (I'm sorry I can not post more than two links because of my reputation) and I think this is not the best solution, I prefer to use cairomm.
This application was written in C using GTK2, and the circles were drawn using gnomecanvas, adding signals in an easy way to each circle; and now I'm moving this application to C++ and GTK3 to renew it.
I'm very new to GTK (and graphical interfaces in general), but I looked for solutions for hours and I don't know what is the best way in order to continue my work.
Thank you for your help :)
It's best to use a canvas library for this such as GooCanvas. Doing it with cairo alone would require you to listen to mouse events on the whole drawing area, and keep track of where the circles were in order to decide which circle the mouse event belongs to - exactly the problem which the canvas library has already solved for you.
If you are having trouble with goocanvasmm documentation, a look at the documentation for GooCanvas' C API combined with knowledge of how the C API translates into C++ will usually suffice. Although the GooCanvasmm documentation seems fairly extensive to me.
I am currently having a problem with Qt graphics view framework namely, I want to clear my QGraphicScene background color and then run a function to take a webcam picture. So far when I use QWidget.repaint the screen only got repaint after about 1 second and by then the camera function has been called and the image captured is always off. Here is how my code currently look like.
//Scene is a QGraphicScene
//View is a QGraphicView
//Camera is a camera object
Scene.setBackgroundBrush(Qt::Blue)
View.repaint()
Camera.Capture()
I have tried wrapping the repaint() call with another function and use signal and slot call but it still fail. I want to know if there is a way to pause the program until the screen has been refreshed.
A QGraphicsView has a bit more going on than most QWidget subclasses and I'm not familiar enough with it to say what is going on for sure but I might venture a guess that your problem is related to the fact that the scene is actually rendered onto the view port widget. Perhaps calling viewport->repaint() will give you the results you are looking for?
Also, unless you really need to be using the webcam in this scenario, you could call ::render() on your scene and pass it a QImage which you could save directly to a file.
I subclassed QGraphicsItem and reimplemented paint.
In paint I wrote something like this for labeling the item:
painter->drawText("Test",10,40);
After some time I think It may be useful to handle labeling with seperate item. So I wrote something like this.
QGraphicsTextItem *label = new QGraphicsTextItem("TEST",this);
setPos(10,40);
But two "TEST" drawing do not appear in the same place on screen. I guess difference may be related with item coordinates - scene coordinates. I tried all mapFrom... and mapTo... combinations inside QGraphicsItem interface but no progress. I want to drawings to appear in the same place on screen.
What I miss?
I assume that you are using the same font size and type in both cases. If the difference in position is very small the reason can be the QGraphicTextItem is using some padding for the text it contains. I would try to use QGraphicsSimpleTextItem that is not going to add fancy stuff internally and see if you still have the same problem. The coordinates system is the same one if you use painter or setPost so that is not the problem. If this doesn't help I will suggest to specify the same rect for both to avoid Qt adding it owns separation spaces.