Change image on StaticBitmap wxWidgets - c++

I would like to have a window, in which a picture changes depending on what is happening during an infinite loop.
Imagine someone walking around and when he leaves a given track, the program should display an arrow towards the direction of the track. Therefore I have a program, which determines the distance between user and track, but I have no idea on how to update the image.
I use code::blocks with wxWidgets and think I have to use the wxStaticBitmap class. (If there is a better way, please tell me.)
I tried with:
while(true)
{
updatePosition();
if(userNotOnTrack)
{
if(trackRightOfUser)
{
StaticDirectionBitmap->SetBitmap("D:\\WindowsDgps\\WindowsDgpsGraphic\\arrow_right.png");
}
}
}
(Note that this snippet is mostly pseudocode, except the StaticDirectionBitmap part.)
On default the Bitmap has a "no_arrow" image. With this I get an error: error: no matching function for call to 'wxStaticBitmap::SetBitmap(const char [51])'|. I see from the documentation that this cannot work, but I have no idea what could.
If anyone knows how to handle this, I would be happy to hear. I remember a few years back, when I tried something similar in C# and failed completely because of thread safety... I hope it is not this hard in C++ with wxWidgets.

SetBitmap takes a wxBitmap parameter not a string. So the call should look something like:
SetBitmap(wxBitmap( "D:\\WindowsDgps\\WindowsDgpsGraphic\\arrow_right.png", wxBITMAP_TYPE_PNG) );
Make sure prior to making this call that the png handler has been added with a call like one of the following:
wxImage::AddHandler(new wxPNGHandler);
or
::wxInitAllImageHandlers();
The easiest place to do this is in the applications OnInit() method.
If you want update the static bitmap from a worker thread, you should throw a wxThreadEvent and then make the call to SetBitmap in the event handler. The sample here shows how to generate and handle these events.

Related

How to use Accelerometer in cocos2dx

I've been trying to get the acceleromter to work in cocos2d-x c++.
I tried to add this function to my scene which a lot of my Google search results said I should:
virtual void didAccelerate(Acceleration *acceleration);
That does however give me an error saying I'm overriding a final function.
Then I found how I could use the EventDispatcher thing for it.
auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(MainScene::accelerated, this));
getEventDispatcher()->addEventListenerWithSceneGraphPriority(accListener, this);
In both of these I had called this function earlier in my scene's init function:
setAccelerometerEnabled(true);
I'm all out of ideas and I need help. On the second "approach" it compiled, but my accelerated function was never called.
Thank you in advance!
I'm using Android so maybe I need to edit something in the AndroidManifest?
The guys at the cocos forums linked me to this:
Cocos docs
As you can see the correct way to go is to use the EventListener approach as described earlier. However you need to call
Device::setAccelerometerEnabled(true);
Calling
setAccelerometerEnabled(true);
From the scene's init doesn't work, you need to call the static method on 'Device'.
So here's how you do it.
Device::setAccelerometerEnabled(true);
auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(MainScene::accelerated, this));
getEventDispatcher()->addEventListenerWithSceneGraphPriority(accListener, this);
Where accelerated is takes these parameters:
void accelerated(Acceleration *acceleration, Event *event);
Of course this function can be called anything as the EventListener takes a function pointer.
Tritzium answered it right. Just wanted point out:
You wont get accelerator events in simulator, you need a device.

Using Cocos2d-x SEL_CallFunc

I'm trying to make a custom sprite, which could receive touch and handle the function as callback.
Okay, first step, receive the touch, easy, we can search it online everywhere.
The one I couldn't do is, I want to make it receive SOMETHING in the class the sprite is created, a function that will be called when the sprite is touched.
I was searching on internet and I think (not really sure) that SEL_Callfunc can do what I want, but I couldn't understand how this one work, so can you guys give me an example please?
For example, my custom class is BSprite, so when I create new object in HelloWorld.cpp, it should be
BSprite* sprite = BSprite::create("HelloWorld.png",HelloWorld::TouchCallback);
Thanks for reading :)
sprite->addTouchEventListener(CC_CALLBACK_0(HelloWorld::onTouchSprite, this));
void HelloWorld::onTouchSprite() {
}
Note: onTouchSprite method should not have any parameters

Weird bug in Qt application

In my application, I have my re-implemented QGraphicsView checking for a mouseReleaseEvent(), and then telling the item at the position the mouse is at to handle the event.
The QGraphicsItem for my view is made up of two other QGraphicsItems, and I check which one of the two is being clicked on (or rather having the button released on), and handle the respective events.
In my Widget's constructor, I set one of the items as selected by default, using the same methods I used when the items detect a release.
When I debugged, I found that for the LabelItem, select is called without a problem from the constructor (and the result is clear when I first start the application). But, when I click on the items, the application terminates. I saw that I was getting into the select function, but not leaving it. So the problem is here.
Which is very weird, because the select function is just a single line setter.
void LabelItem::select()
{
selected = true;
}
This is the mouseReleaseEvent;
void LayerView::mouseReleaseEvent(QMouseEvent *event)
{
LayerItem *l;
if(event->button() == Qt::LeftButton)
{
l = (LayerItem *) itemAt(event->pos());
if(l->inLabel(event->pos()))
{ //No problem upto this point, if label is clicked on
l->setSelection(true); //in setSelection, I call select() or unselect() of LabelItem,
//which is a child of LayerItem, and the problem is there.
//In the constructor for my main widget, I use setSelection
//for the bottom most LayerItem, and have no issues.
emit selected(l->getId());
}
else if(l->inCheckBox(event->pos()))
{
bool t = l->toggleCheckState();
emit toggled(l->getId(), t);
}
}
}
When I commented the line out in the function, I had no errors. I have not debugged for the other QGraphicsItem, CheckBoxItem, but the application terminates for its events as well. I think the problem might be related, so I'm concentrating on select, for now.
I have absolutely no clue as to what could have caused this and why this is happening. From my past experience, I'm pretty sure it's something simple which I'm stupidly not thinking of, but I can't figure out what.
Help would really be appreciated.
If the LabelItem is on top of the LayerItem, itemAt will most likely return the LabelItem because it is the topmost item under the mouse. Unless the LabelItem is set to not accept any mouse button with l->setAcceptedMouseButtons(0).
Try to use qgraphicsitem_cast to test the type of the item. Each derived class must redefine QGraphicsItem::type() to return a distinct value for the cast function to be able to identify the type.
You also could handle the clicks in the items themselves by redefining their QGraphicsItem::mouseReleaseEvent() method, it would remove the need for the evil cast, but you have to remove the function LayerView::mouseReleaseEvent() or at least recall the base class implementation, QGraphicsView::mouseReleaseEvent(), to allow the item(s) to receive the event.
I have seen these odd behaviours: It was mostly binary incompatibility - the c++ side looks correct, and the crash just does not make sense. As you stated: In your code the "selected" variable cannot be the cause. Do you might have changed the declaration and forgot the recompile all linked objects. Just clean and recompile all object files. Worked for me in 99% of the cases.

wxProgressDialog somehow keeping app alive after death?

I'm having a strange problem with wxWidgets. I have the following code
MyFrame::OnDoSomeLongThing(...) {
progScreen = new wxProgressDialog(text,text,number,this,wxPD_AUTO_HIDE); // wxProgressDialog *progScreen is class member
doPartOfThing() // calls the update method at the end of it
....
doLastPartOfThing() // again calls update method that pushes value to 100/100
progScreen->Destroy();
}
MyFrame::update() {
progScreen->Update(newValue);
}
Now here's the thing. I can literally comment out the lines relating to progScreen, just let the process go without using a progress dialog, after all is said and done, my apps exits gracefully when I close the main window.
However, just the use of the progress dialog is somehow extending the life of the application. I've tried Destroy(), I've tried simply 'delete progScreen', and both, every time: I'll close the main frame, the process keeps running, and at some point exits with some astronomical number. The only thing I could think might be relevant, is that the doPartsOfThings methods may call boost::this_thread::sleep, because it involves waiting and whatnot down in my model class. But this shouldn't have anything to do with my problem. Or maybe it does... EDIT: I do want to emphasize that progScreen->Update() IS being called from the main (GUI) thread.
So I ask, am I using a wxProgressDialog correctly? If not, how should it be used?
Thanks for your help!
EDIT:
Well... it turns out that removing wxPD_AUTO_HIDE fixed the problem. I'm still not quite sure what the problem is, but the dialog even still behaves as before. App closes as expected.
I think that you need to override the wxApp method that closes the application so that it closes the wxProgressDialog object before it quits.
wxApp::OnExit
virtual int OnExit()
Override this member function for any processing which needs to be
done as the application is about to exit. OnExit is called after
destroying all application windows and controls, but before wxWidgets
cleanup. Note that it is not called at all if OnInit failed.
The return value of this function is currently ignored, return the
same value as returned by the base class method if you override it.
You will need something like, assuming progScreen is a public attribute of your frame
int myApp::OnExit()
{
(MyFrame*)(GetTopWindow())->progScreen->Destroy()
return wxApp::OnExit();
}

C++: Cannot instantiate a pointer directly

This is an SDL problem, however I have the strong feeling that the problem I came across is not related to SDL, but more to C++ / pointers in general.
To make a long story short, this code doesn't work (edited to show what I really did):
player->picture = IMG_Load("player");
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I see nothing on the screen. However, when I do it like this, it works:
SDL_Surface* picture = IMG_Load("player.png");
player->picture = picture;
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I can see the little guy just fine.
The real problem is that I cannot instantiate Player::picture directly. Even when I try
picture = IMG_Load("player.png")
in player.cpp, I end up with a nullpointer.
I am so stupid. Turns out like I forgot the file extension ".png" every time I tried to store the surface in Player::picture, and conveniently remembered to add it every time I stired it in an SDL_Surface declared in main.cpp.
I had the feeling I was overlooking something really simple here, but this is just embarassing. What's a fitting punishment for this?
What data type is player->picture? What type does IMG_Load return? It's really hard to come up with a scenario where saving an expression in a temporary variable changes the result, unless a type conversion is involved.
And I wouldn't call this pointer instantiation. You're instantiating an instance of some picture type and storing a pointer to it.
This is why you should always check to see what IMG_Load() returns...
SDL_Surface* picture = IMG_Load("player.png");
if (picture == NULL) {
// there was obviously some sort of error.
// what does SDL_GetError() say?
}
Some SDL functions return -1 if there is an error. Just check the documentation and make sure you're checking your function returns. These steps make debugging a lot easier.