Graphical User Interface
Graphical User Interface
hello i have only one question... can i use wx to create a gui for a command line tool like tar? i mean in a terminal can i type "tar -xf archive.tar" i will that my gui do this for me, i think i have found the funktions in wx they called;
"Process control functions"
::wxExecute
::wxExit
::wxKill
::wxGetProcessId
::wxShell
::wxShutdown
p.s.: sorry for my english im german...
"Process control functions"
::wxExecute
::wxExit
::wxKill
::wxGetProcessId
::wxShell
::wxShutdown
p.s.: sorry for my english im german...
-----------------------
m.f.g
dennis
-----------------------
iBook G4 12" 1,2GHz 256MB
MacOSX 10.3.8
m.f.g
dennis
-----------------------
iBook G4 12" 1,2GHz 256MB
MacOSX 10.3.8
Hi!
For further questions: Send me a PM in german if you like.
Yes, you can.hello i have only one question... can i use wx to create a gui for a command line tool like tar?
For further questions: Send me a PM in german if you like.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
- ABX
- Can't get richer than this
- Posts: 810
- Joined: Mon Sep 06, 2004 1:43 pm
- Location: Poznan, Poland
- Contact:
Just a minor note (thought not private becase is can be related to all readers) shortcuts like 'PM' are out of context (senseless) for those of us who is reading this forum through RSS Just in case you could be surprised by somebody in the future who did not followed your advice because missed its meaningupCASE wrote:For further questions: Send me a PM in german if you like.
ABX
CVS Head, 2.8.X
wxMSW, wxWinCE, wxPalmOS, wxOS2, wxMGL, bakefile
gcc 3.2.3, bcc 5.51, dmc 8.48, ow 1.6, vc 7.1, evc 3/4, pods 1.2
wxMSW, wxWinCE, wxPalmOS, wxOS2, wxMGL, bakefile
gcc 3.2.3, bcc 5.51, dmc 8.48, ow 1.6, vc 7.1, evc 3/4, pods 1.2
Hi!
I answered the original question in a private message in the forum (located at http://forums.wxwidgets.org/ (Ok ABX?? )).
Here's a quick outtake and answer:
For simply starting a program and capturing its output use
"command" is the command to use with all needed arguments, output and errors are Arrays storing the returned lines from stdout and stderr.
If you have a more complex task and need the program running asynchronously in background, use
You'll have to use a wxProcess and capture its OnTerminate() event. You can get the in- and output by using wxProcess::GetInputStream() and wxProcess::GetOutputStream() .
Use
for example to read the first line of the programs stdout output.
To "live" capture the output of a longer running task, catch OnIdle() events and check if input is available for the stream.
For a nice example check the "exec" sample in the sample folder. The menu "Exec"->"Capture command output" shows what you want. Synchronous execution shows the first thing I mentioned, asynchronous execution the second case.
I answered the original question in a private message in the forum (located at http://forums.wxwidgets.org/ (Ok ABX?? )).
Here's a quick outtake and answer:
For simply starting a program and capturing its output use
Code: Select all
long wxExecute(const wxString& command, wxArrayString& output, wxArrayString& errors)
If you have a more complex task and need the program running asynchronously in background, use
Code: Select all
long wxExecute(const wxString& command, int sync = wxEXEC_ASYNC, wxProcess *callback = NULL)
Use
Code: Select all
wxInputStream* stream = myProcess->GetInputStream();
wxTextInputStream tis(*stream);
wxString msg;
msg << tis.ReadLine();
To "live" capture the output of a longer running task, catch OnIdle() events and check if input is available for the stream.
For a nice example check the "exec" sample in the sample folder. The menu "Exec"->"Capture command output" shows what you want. Synchronous execution shows the first thing I mentioned, asynchronous execution the second case.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
-
- Earned a small fee
- Posts: 17
- Joined: Tue Jan 10, 2006 12:52 am
- Location: New Zealand
Hi,upCASE wrote: To "live" capture the output of a longer running task, catch OnIdle() events and check if input is available for the stream.
I have a code as follow which tries to get output from a console program (called console.exe) and display it in a wxTextCtrl, but I can only get the first output.... was reading this post which I found extremely helpful, but was wondering if I can get some guidance on how to do this (capture the output of a longer running task)? I tried to look at the sample/exec example, but couldn't follow that at all
Code: Select all
void main::OnButtonRunClick( wxCommandEvent& event )
{
wxString cmd = "console.exe";
wxProcess *process = new wxProcess(this);
process->Redirect();
if (wxExecute(cmd, wxEXEC_ASYNC, process))
{
wxString msg;
wxInputStream *iStream = process->GetInputStream();
wxTextInputStream tStream(*iStream);
msg = tStream.ReadLine();
mTextCtrl->AppendText(msg);
}
event.Skip();
}
Have a look at the exec example. It implements OnIdle() for reading the output of async processes.
The example uses a derived class (MyPipedProcess), but for only one process you can do that with wxProcess itself.
Implement OnIdle(). Start the process like you did. In OnIdle(), check if IsInputAvailable() returns true for the process. Then use GetInputStream() to read the input. In the same way hanlde IsErrorAvailable() and GetErrorStream().
The example uses a derived class (MyPipedProcess), but for only one process you can do that with wxProcess itself.
Implement OnIdle(). Start the process like you did. In OnIdle(), check if IsInputAvailable() returns true for the process. Then use GetInputStream() to read the input. In the same way hanlde IsErrorAvailable() and GetErrorStream().
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
-
- Earned a small fee
- Posts: 17
- Joined: Tue Jan 10, 2006 12:52 am
- Location: New Zealand
I'm guessing in order to be able to use the variable which I've called "process" in my OnIdle(), I'd need to define "process" outside of my "OnButtonRunClick()" function right? Ok now this is going to be a really stupid question, but where would I define my "process"? At the moment I have 2 files, one called "main.h" and one called "main.cpp", in "main.h" I've defined myupCASE wrote:Implement OnIdle(). Start the process like you did. In OnIdle(), check if IsInputAvailable() returns true for the process. Then use GetInputStream() to read the input. In the same way hanlde IsErrorAvailable() and GetErrorStream().
Code: Select all
class main : public wxDialog
{
DECLARE_DYNAMIC_CLASS( main )
DECLARE_EVENT_TABLE()
public:
/// Constructors
main( );
main( wxWindow* parent, wxWindowID id = SYMBOL_MAIN_IDNAME, const wxString& caption = SYMBOL_MAIN_TITLE, const wxPoint& pos = SYMBOL_MAIN_POSITION, const wxSize& size = SYMBOL_MAIN_SIZE, long style = SYMBOL_MAIN_STYLE );
...
wxProcess *process;
};
Code: Select all
main::main( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
process = new wxProcess(this);
process->Redirect();
Create(parent, id, caption, pos, size, style);
}
Code: Select all
void main::OnButtonRunClick( wxCommandEvent& event )
{
wxString cmd = "console.exe";
if (wxExecute(cmd, wxEXEC_ASYNC, process))
{
wxString msg;
wxInputStream *iStream = process->GetInputStream();
wxTextInputStream tStream(*iStream);
msg = tStream.ReadLine();
mTextCtrl->AppendText(msg);
}
event.Skip();
}
Any help is much appreciated
PS: I'm using MSVC 7.1, and I used DialogBlocks to generated part of the codes
Don't create the process before the Create() function wass called. I'd create the process in the OnButton() method if it doesn't exist allready. Set it to NULL in the constructor and in the OnButton() method do something likechocobo_ff wrote:Obviously I did something really stupid here cos when I run the program (it compiled fine), it gave me a "Debug Error!... DAMAGE: after Normal block (#2323) at 0x00DD21A8..."Code: Select all
main::main( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) { process = new wxProcess(this); process->Redirect(); Create(parent, id, caption, pos, size, style); }
Code: Select all
if(!process)
{ process = new wxProcess(this);
process->Redirect();
}
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
-
- Earned a small fee
- Posts: 17
- Joined: Tue Jan 10, 2006 12:52 am
- Location: New Zealand
Ok I will try that first thing tomorrow morning and let you guys know how I'm going with it. Just another question while its on my mind, would I do similar thing in OnIdle(), i.e. check if process has been created and input stream is != NULL ? The problem I had before is that the process would be called at OnIdle() straight after the program starts, and that crashes the program, so that's why I tried to create the process before Create()?upCASE wrote: Don't create the process before the Create() function wass called. I'd create the process in the OnButton() method if it doesn't exist allready. Set it to NULL in the constructor and in the OnButton() method do something likeAlso check if the input stream is != NULL.Code: Select all
if(!process) { process = new wxProcess(this); process->Redirect(); }
Exactly. Check if the process exists, if it has input and if the input is not NULL.chocobo_ff wrote:Ok I will try that first thing tomorrow morning and let you guys know how I'm going with it. Just another question while its on my mind, would I do similar thing in OnIdle(), i.e. check if process has been created and input stream is != NULL ? The problem I had before is that the process would be called at OnIdle() straight after the program starts, and that crashes the program, so that's why I tried to create the process before Create()?
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4
"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
-
- Earned a small fee
- Posts: 17
- Joined: Tue Jan 10, 2006 12:52 am
- Location: New Zealand
Ok I just tried to put the code you showed above in my program... and it crashed when I run it, so I tried to go to debug mode, and when it goes to the lineupCASE wrote: Don't create the process before the Create() function wass called. I'd create the process in the OnButton() method if it doesn't exist allready. Set it to NULL in the constructor and in the OnButton() method do something likeAlso check if the input stream is != NULL.Code: Select all
if(!process) { process = new wxProcess(this); process->Redirect(); }
Code: Select all
if (!process)
Code: Select all
wxProcess *process;
-
- Earned a small fee
- Posts: 17
- Joined: Tue Jan 10, 2006 12:52 am
- Location: New Zealand
Sorry completely missed that I've done it just before you replied and it sort of works now, but the problem is that it crashes in the OnIdle() part after a while, I think whats happening is the console program I'm calling is finished before my wxWidgets GUI gets all the outputs, so it only gets say the first 3 out of the 10 outputs.upCASE wrote:Did you initialize process to NULL??
Code: Select all
if (mProcess)
{
if (mProcess->IsInputAvailable())
{
wxString msg;
wxInputStream *stream = mProcess->GetInputStream();
wxTextInputStream tStream(*stream);
msg = tStream.ReadLine();
mTextCtrl->AppendText(msg + "\n");
}
}
P.S.: A bit about my console program - it takes a value from my wxWidgets program, say 15, and then it runs from 0 - 14 (total of 15 numbers) with a 100ms pause in between.