As I understand it, you just want a window that display the progress
of a computation in ASCII readable text.
Here's how I would approach it.
1. Write a program that creates a window. This should be trivial,
something you already know how to do.
2. Derive a class from your window class and use that instead, e.g.,
class myFrame: public Gtk::Window
{
blah blah blah
}
myFrame frame;
Gtk::Main::run(frame);
3. Modify the constructor for myFrame to start a thread, something
like this:
Glib::Thread *m_thread = Glib::Thread::create(sigc::mem_fun(*this,
&myFrame::dataThread), true);
You'll need to add "void dataThread(void)" to your class. Just make
the thread write to stdout for now.
4. Put your computation in this new thread.
5. Put a scrolling text widget in your window. Make sure that you
know how to write to it.
Now here's where it gets tricky.
You can probably write to the text widget from your thread. Try
it. In your thread, write stuff to the text widget.
The problem is that you may have a collision between the thread and
the main part of the program, e.g., you try to move the window at
the same time you're updating the thread. For that you need to set
up a dispatcher. You should be able to do something like this:
A. Add Glib::Dispatcher m_dispatcher to your class definition.
B. Add a prototype "void dispatcherWork(void);" to your class
definition.
C. You're going to link the dispatcher to this routine, so that the
routine (dispatcherWork) can be called in the context of the main
thread, but by the secondary thread you created.
In your constructor, add m_dispatcher.connect(sigc::mem_fun(*this,
&myFrame::dispatcherWork));
D. Make the code in your compute thread that writes to the text
widget write to a buffer instead.
E. Create your dispatcherWork() routine. It should read from the
buffer and write to the text widget.
F. In your thread, after you write to the buffer, call the
dispatcher like this: m_dispatcher();
When you call the dispatcher, the main thread will update the widget
synchronously with other window activities (like moves or repaints)
that may be happening.
This is just an outline, but I think this approach is much more
productive than messing with signals, since this approach lets you
write asynchronously to the window, which I believe is what you
want.
-- Alan
On 7/31/2013 4:57 AM, L. D. James
wrote:
Thanks, Ian. And yes. I know that my code is performing outside
the gui environment. I gave the example so that the community
would understand what I was trying to do and tell me what changes
had to happen to have the code perform inside the gui environment.
I have already found examples that use the new version you
mention. I'm using that version now and still having the same
problem. This is because I don't know where to place the lines to
perform output to the gui window.
I'm baffled that there isn't anyone in the community that has
every sent new text to a gui window without the user having to
press a key. It's similar to the way Windows used to perform a
fresh install. You had to sit at the console and keep pressing
keys to continue. They finally went to a method to allow you to
answer a few questions, then you can proceed with the install and
look at the status of the update without having to sit there and
press keys.
I'm glad, that from your description that you understand the
objective and have put it in very professional and descriptive
words. Hopefully the developer will add and example to the
elaborate code snippets of the documentation.
I'm investigating the use of sigc::timeout. I find that the
button widget uses it. I'm trying to figure out how to bypass the
button and perform the button function without pressing the
button.
Thanks again for all your input and any other hints that might
come to your mind of which I should look at.
-- L. James
--
L. D. James
ljames apollo3 com
www.apollo3.com/~ljames
On Wed, 2013-07-31 at 22:37 +1200, Ian Martin wrote:
Hi,
On review, you're using Gtk::Main::run(), which is in the
process of getting deprecated, and probably shouldn't be used in
new code unless you're working with a gtkmm version <3.0 The
progress bar example in the book has the "new" version,
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
ExampleWindow window;
//Shows the window and returns when it is closed.
return app->run(window);
which you should probably be using instead.
Regarding the original question, your underlying issue is you're
trying to modify information in isolation from the GUI
environment, but want the GUI to respond. The gtkmm window is
created on the display with Gtk::Main::run(window) or
app->run(window); in the code you started with, that's the
last line of the main function, so any changes before that will
happen before it becomes visible.
The examples in the book all(?) contain at least 3 files: one
brief and standardised for main.cpp, and two for the
ExampleWindow cpp and h files, where all the work is done (
including any terminal output). This helps emphasise that gtkmm
code is by definition for a GUI program. If you connect a
member function to a sigc::timeout then you should see the
behaviour you want.
Ian
On 31/07/13 14:02, L. D. James wrote:
Thanks, Ian. This is a great start.
I'll spend some time trying to figure out how to output to a
text window or label rather than the graphics bar.
I knew this was possible. I'm very surprise it's so hard to
find a natural way to do it with actual text.
After I get it done, I'll post the resolution back to the
group for anyone else that is stuck.
-- L. James
--
L. D. James
ljames apollo3 com
www.apollo3.com/~ljames
On Wed, 2013-07-31 at 12:48 +1200, Ian Martin wrote:
Hi,
Have you looked at the code for the progress bar example?
https://developer.gnome.org/gtkmm-tutorial/stable/sec-progressbar.html.en
Ian.
On 31/07/13 09:33, L. D. James wrote:
> On 07/30/2013 04:53 PM, Moh B. wrote:
>> //main.cpp:
>> //-----------
>> // Look at this modified code and pay attention to the order of
>> execution and call th the functions
>> #include <gtkmm.h>
>> #include <iostream>
>>
>> using namespace std;
>>
>> int main(int argc, char* argv[])
>> {
>> Gtk::Main kit(argc, argv);
>>
>> Gtk::Window window;
>> Gtk::TextView textview;
>> Gtk::Label label;
>>
>> string mylabeltext = "This is the first line of text in my gui
>> window.\n";
>>
>> window.set_default_size(600, 360);
>> window.set_title("Gtkmm Programming - C++");
>> window.set_position(Gtk::WIN_POS_CENTER);
>>
>> label.show();
>> window.add(label);
>>
>> label.set_text(mylabeltext);
>>
>> mylabeltext += "About to run some routines...\n";
>>
>> label.set_text(mylabeltext);
>>
>> cout << "An initial line has been set to the gui window." <<
>> endl;
>> // The Gui Window is displayed
>> //==> YOURS Gtk::Main::run(window);
>> // Now my main program has performed some functions and wants to
>> update
>> // the console and the gui window.
>> cout << "Continuing after various functions and processing..." <<
>> endl;
>> //A MODIFICATION HERE '+=' instead of yours '=''
>> mylabeltext += "Showing the results of the functions and
>> processing.";
>> label.set_text(mylabeltext);
>> // AND NOW
>> Gtk::Main::run(window);
>> return 0;
>> }
>> //----------------------------------------------
>> //code end
>>
>> /////////////// Makefile ///////////////////
>> #Begin of Makefile
>> all:
>>
>> @echo " "
>> @echo " 1- Compiling..."
>> g++ -Wall -g -c *.cpp `pkg-config gtkmm-3.0 --cflags`
>>
>> @echo " "
>> @echo " 2- Linking..."
>> g++ -Wall -g *.o `pkg-config gtkmm-3.0 --libs` -o
>> Gtkmm34-popup-menu-test
>>
>> @echo " "
>> @echo " DONE!!!";
>> # @echo " "
>> chmod +x Gtkmm34-popup-menu-test
>> ls . -all
>>
>> clean:
>> rm *.o Gtkmm34-popup-menu-test
>>
>> /////////////// Makefile ///////////////////
>> #End of Makefile
>>
>
> How are you doing, Moh B.
>
> I believe you misunderstood my problem. I can output all the text out
> to the gui window without problems. However, what I'm trying to do is
> output the text after an operation has taken place. I should have put
> sleep() functions to represent some operation taking place. I want to
> give the user a status of what is taking place between operations.
>
> I updated the code to better represent this.
>
> At present I see the output at each stage on the console. However, the
> gui window isn't updated. It doesn't show anything until after all
> the functions have completed (in this case sleep() functions.
>
> In the actually program some of the functions will take a few minutes
> and some of them might take over an hour. I don't want the user to be
> left with a no status update for the entire time, or between operations.
>
> Notice how the console is output immediately. Then a sleep function.
> Then the status is updated again informing the user how long the
> function took. Then another function (in this case a sleep() function.
>
> //code begin:
> //main.cpp:
> //-----------
> // Look at this modified code and pay attention to the order of
> execution and call th the functions
> #include <gtkmm.h>
> #include <iostream>
>
> using namespace std;
>
> int main(int argc, char* argv[])
> {
> Gtk::Main kit(argc, argv);
>
> Gtk::Window window;
> Gtk::TextView textview;
> Gtk::Label label;
>
> string mylabeltext = "This is the first line of text in my
> guiwindow.\n";
>
> window.set_default_size(600, 360);
> window.set_title("Gtkmm Programming - C++");
> window.set_position(Gtk::WIN_POS_CENTER);
>
> label.show();
> window.add(label);
>
> label.set_text(mylabeltext);
>
> mylabeltext += "About to run some routines...\n";
>
> label.set_text(mylabeltext);
>
> cout << "An initial line has been set to the gui window." << endl;
>
> sleep(60); // This is the estimated time for a function to run.
> Some of them takes an hour.
> mylabeltext += "Continuing after the first fundtion that took 60
> seconds\n";
> cout << "Continuing after various functions and processing..." <<
> endl;
> label.set_text(mylabeltext);
>
> sleep(60); // This represents another stage of processes and
> operations. I'm attempting to update
> // the status to the user.
> //A MODIFICATION HERE '+=' instead of yours '=''
> mylabeltext += "Other events are taking place that has taken
> another 60 seconds\n";
> cout << "Other events have taken place" << endl;
> label.set_text(mylabeltext);
> // AND NOW
> Gtk::Main::run(window);
> return 0;
> }
> //----------------------------------------------
> //code end
>
> -- L. James
>
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
https://mail.gnome.org/mailman/listinfo/gtkmm-list
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
https://mail.gnome.org/mailman/listinfo/gtkmm-list
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
https://mail.gnome.org/mailman/listinfo/gtkmm-list
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
https://mail.gnome.org/mailman/listinfo/gtkmm-list
|