Hey guys I'm new in c++ wxwidgets programming.
I would like to know the easiest way to put an image into a button.
I tried :
button1 = new wxBitmapButton(side_panel, wxID_ANY, wxBitmap("image.png",wxBITMAP_TYPE_PNG), wxPoint(150,30), wxSize(30, 30),wxBORDER_NONE);
But I always get the same error:
If you expand the error dialog you see, you should see more information about the error, but my guess is that the image simply can't be found. You should check that the file image.png indeed exists in the current working directory of your program, i.e. the directory that you run it from, assuming you don't change it later.
You should also actually check for errors in your programs, even simple ones, i.e.
wxBitmap bmp("image.png");
if (!bmp.IsOk()) {
... handle the error somehow instead of blithely using an invalid bitmap ...
}
Related
I've been trying to make a simple wxWidgets program with just a button with a picture on it. I've been able to make the button with the image on it easily enough, but my problem arises when including it.
So far, I've only been able to fetch the image during run-time (the image has to be in the same folder as the .exe file; otherwise, I get error 2: the system cannot find the file specified). With this method, I have no problems -- the program works just fine. What I'm trying to do, however, is to #include the file so that it is embedded during compile-time, so that it doesn't need to be available during run-time.
I've tried #including the file (both as .png and as .xpm), and I've also tried adding it to the resource includes (this is on Visual Studio 2017). Neither of these worked -- the first method still required the image to be in the same folder, and the second failed during compilation (as far as I can tell, it wasn't able to read the .xpm file).
Here is the relevant code, if it helps:
/*relevant includes*/
#include "happyFace.png" //this isn't working. the file is still needed
||
#include "happyFace.xpm" //ditto
/*I have also tried putting these lines in the resource includes.*/
/*code*/
wxInitAllImageHandlers();
wxBitmap bitmap("happyFace.xpm", wxBITMAP_TYPE_XPM); //only works in same directory at run-time
||
wxBitmap bitmap("happyFace.png", wxBITMAP_TYPE_PNG); //ditto
wxButton *button = new wxButton(this, ID_BMP_BUTTON);
button->SetBitmap(bitmap);
//the rest of the button programming and stuff
Sorry if I haven't provided enough information; I can provide more if necessary. I would really appreciate any help. Thanks!
Two possibilities... Number 1 is simplest. It's been a long time since I wrote the code I'm looking at, so the details are fuzzy.
In Visual Studio, Solution Explorer, add the image into the resource files. Assume the name of the resourse is sample.rc. Then it can be used like so to set the main icon...
SetIcon(wxICON(sample));
Method 1 must be used in order for MS Windows Explorer to display the main icon. I do not remember how to use .rc resources for other things, but it should be easy to figure out.
I did it this way before I discovered VS resource (.rc) files. Compile the file-image into the program "by hand." In other words, write a program that will read an image file and produce bit-for-bit copy in a .cpp file. Then compile that .cpp into the program. Here I have the file-image in memory as an object named dj::main_cursor. Note that the in-memory version is a bit-for-bit copy of a .cur file.
dj::captured_file &c1file(dj::main_cursor);
wxMemoryInputStream cistr(c1file.contents, c1file.size);
cursor1 = wxCursor(wxImage(cistr, wxBITMAP_TYPE_CUR));
FYI, I defined the structure dj::captured_file like so:
struct captured_file {
const char *name;
const unsigned long size;
const void *contents;
captured_file(const char*fn, size_t sz, const void*c)
: name(fn)
, contents(c)
, size(sz)
{}
};
See also, Embedding PNG Images into Windows RC Files
I found some other documentation.
Resources and Application Icon All applications using wxMSW should
have a Windows resource file (.rc extension) and this file should
include include/wx/msw/wx.rc file which defines resources used by
wxWidgets itself.
Among other things, wx.rc defines some standard icons, all of which
have names starting with the "wx" prefix. This normally ensures that
any icons defined in the application's own resource file come before
them in alphabetical order which is important because Explorer
(Windows shell) selects the first icon in alphabetical order to use as
the application icon which is displayed when viewing its file in the
file manager. So if all the icons defined in your application start
with "x", "y" or "z", they won't be used by Explorer. To avoid this,
ensure that the icon which is meant to be used as the main application
icon has a name preceding "wxICON" in alphabetical order.
http://docs.wxwidgets.org/3.1.0/page_port.html
Here is how you should do it:
#include "happyFace.xpm"
wxBitmap bitmap = wxBitmap( happyFace ); // assuming the variable name is "happyFace" inside the xpm
Then you will use bitmap object just like usual. Assuming that the file happyFace.xpm is available for compilation.
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.
I'm pretty new to QT so maybe the answer to this question is simple. I'm making a terminal for our freescale car this year which is just a car that autonomously goes around a track. We're using line-scan cameras which give you a line of data 128 pixels long that you refine into either "white" or "black" (edges of the track) values. Last year the team made this terminal in QT which is used for modifying certain coefficients, stopping the motors, and all kinds of stuff through bluetooth. A text browser was used to display what the line cameras see.
Last year they combined the two cameras to create one image, but we're re configuring them this year, and they will produce two different images of the track. Naturally, I need to make two text browsers, one for each camera. Should simply be a case of copying code and changing some names right? Well apparently not.
I placed the text browser in the window using the design gui, named it, and made its settings match the other browser. I went into the code for the main window c file and adapted the code there. For every reference to the other browser I made sure one was an equal line of code for this one. When I was done and went to build the project, it told me that the browser wasn't a member of 'UI::MainWindow,' and pointed me to the ui_mainwindow.h file. So I went into that header and did the same thing in there. But when I built that, it gave me the error:
...\ui_mainwindow.h:1363: error: C2065: 'tb_camera_out_close' : undeclared identifier
How can that be? There doesn't appear to be any other reference to the other text browser and it works fine. How do I go about declaring this? Shouldn't the gui interface have done it for me when I placed it?
Here's the code from the main window's C file that is involved:
ui->tb_camera_out->setText(msgs_received[1] + '\n' + ui->tb_camera_out->toPlainText());
ui->tb_camera_out_close->setText(msgs_received[2] + '\n' + ui->tb_camera_out_close->toPlainText());
tb_camera_out is the old camera code(I am aware that the toplaintext() part won't work, I'm also attempting to get the text to scroll down instead of up like a track would if you were actually driving but I need to fix this major issue first)
Here's the code from the header that I added:
tb_camera_out = new QTextBrowser(centralWidget);
tb_camera_out->setObjectName(QStringLiteral("tb_camera_out"));
sizePolicy.setHeightForWidth(tb_camera_out->sizePolicy().hasHeightForWidth());
tb_camera_out->setSizePolicy(sizePolicy);
tb_camera_out->setMinimumSize(QSize(450, 0));
tb_camera_out->setMaximumSize(QSize(16777215, 16777215));
tb_camera_out->setStyleSheet(QLatin1String("background-color: rgb(0, 0, 0);\n" "color: rgb(31, 234, 0);"));
gridLayout_4->addWidget(tb_camera_out, 1, 0, 1, 5);
tb_camera_out_close = new QTextBrowser(centralWidget);
tb_camera_out_close->setObjectName(QStringLiteral("tb_camera_out_close"));
sizePolicy.setHeightForWidth(tb_camera_out_close->sizePolicy().hasHeightForWidth());
tb_camera_out_close->setSizePolicy(sizePolicy);
tb_camera_out_close->setMinimumSize(QSize(450, 0));
tb_camera_out_close->setMaximumSize(QSize(16777215, 16777215));
tb_camera_out_close->setStyleSheet(QLatin1String("background-color: rgb(0, 0, 0);\n" "color: rgb(31, 234, 0);"));
Again, the old code is at the top with the references to tb_camera_out. The stuff I added is associated with tb_camera_out_close.
I seem to have solved the problem. Strangely enough, to fix the errors that were showing up I not only had to edit that header, but I then had to delete it and run qmake to restore it. I then had to delete all the past builds to get the thing to even show up when I ran it.
I'm having a bit of trouble in my attempts to learn WXWidgets. I'm currently trying to work with file Dialogs, and I've got one opening just fine. But I run into trouble whenever I try to apply styles to the window. I get an undeclared identifier for whatever style I use.
My code is as follows (yes, I know, hello world app. I'm experimenting with all the things I need to learn to do before actually making a fully fledged app)
#include "wx/wx.h"
#include "wx/filedlg.h"
#include "HelloWorldApp.h"
IMPLEMENT_APP(HelloWorldApp)
bool HelloWorldApp::OnInit()
{
wxFrame *frame = new wxFrame((wxFrame*) NULL, -1, _T("Hello wxWidgets World"));
wxFileDialog* OpenDialog = new wxFileDialog(frame, _("Choose a file to open"), wxEmptyString, wxEmptyString,
_("Image Files (*.jpg, *.png, *.gif, *.bmp)|*.jpg;*.png;*.gif;*.bmp|Sound Files (*.wav, *.mp3)|*.wav;*.mp3"),
wxFD_MULTIPLE);
frame->CenterOnScreen();
frame->Show(true);
OpenDialog->ShowModal();
SetTopWindow(frame);
return true;
}
It runs just fine without the "wxFD_MULTIPLE" argument. I'm using version 2.8.12 of wxWidgets.
Thanks for reading. I really appreciate any help or guidance anyone can give. Sorry if it's something really obvious I'm missing.
In very old wxWidgets versions (2.6), this style was known as wxMULTIPLE but wxFD_MULTIPLE is definitely available in any 2.8.x version. You should give the (beginning of) the errors you get to allow us to understand what is really going on.
Completely independently, your code is wrong because it contains a memory leak: the dialog must be destroyed as modal dialogs are exceptions to the usual rule that all windows should be allocated on the heap and can be allocated on the stack, i.e. used as simple local variables, see the example in the documentation. Looking at the "dialogs" sample code is also strongly recommended.
I am trying to load a Nib from a C++ constructor with Objective C++. I have searched and found enough examples to get some code together but it doesn't display the window. Or any windows for that matter.
Here is an example of the contructor:
JokeSystem::JokeSystem() : fileSystem("/Library/Application Support/Jokes/")
{
try
{
randSystem = new RandSelect<std::string>
(fileSystem.getAllFileContents("%\n"));
}
catch (std::ifstream::failure)
{
NSWindowController * errorWindowControl = [[NSWindowController alloc]
initWithWindowNibName:#"ErrorWindow"];
[errorWindowControl showWindow: nil];
}
}
The purpose of the contructor is to load the contents of a directory into a string. What I am try to do is display the error window when the files fail to open.
ErrorWindow.nib has a single window with an OK button and a NSTextView for the error, I set up a NSWindowController in the nib and connected it to the window.
My only link has been that most examples show this [errorWindowControl showWindow: self];
rather than showWindow: nil but because this is a C++ constructor I it doesn't have self and this doesn't work.
If it matters this contructor is called from the awakeFromNib method of the MainMenu.nib's primary NSObject.
Thanks
A bit of an odd way to approach Cocoa. I would encourage you to step back, learn Objective-C and then write your application with an Objective-C based Cocoa UI layer on top of whatever backing store or model layer you have.
In any case, there isn't anything particularly wrong with that code (save for the odd design).
The first thing to check is the return value of -initWithWindowNibName:. Is errorWindowControl actually non-nil? If it is nil, then the NIB failed to load.
How are you writing the Cocoa application itself? Standard app bundle using Xcode, I hope?
Also, you shouldn't be hardcoding the path to /Library/Application Support/. Actually, your application shouldn't use that directory as the only storage location; many users won't have write access to that directory and won't be able to install your app without administrator access.