Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread Andrew Potter
Mr. James,
This reply has 3 examples. The last time I sent you a complete
solution you never indicated how it was insufficient, so please be
sure read this entire message.

The minimum amount of lines to use a TextView:

//== Example 1 Begin //
#include gtkmm.h

int main(int argc, char *argv[]) {
Glib::RefPtrGtk::Application app =
Gtk::Application::create(argc, argv, com.example);
Gtk::Window win;
Gtk::TextView tv;

tv.get_buffer()-set_text(Hello world);
win.add(tv);
win.show_all();
app-run(win);
return 0;
}
//== Example 1 End //

In your previous emails you have been expressing a desire to output
the result of some long-lasting process to your window. As your
problem was posed to the list it was a contrived problem that had no
simple solution. Most GUI programs start operations by having the user
interact with the window, either by pressing a button or selecting a
menu item.

Nonetheless, I have created another example program that performs a
blocking operation in thread and changes the value of a TextView when
the operation is finished. Note that in the quest for minimality I am
utilizing some features of Gtkmm and C++ that are rarely shown in
beginner examples (such as the ref-to-pointer and sigc::ref()).

This example is 34 lines with no comments or whitespace. But I have
gone ahead and added comments.

//== Example 2 Begin //
#include gtkmm.h
#include unistd.h /* for sleep() */

void cleanup_thread(Glib::Threads::Thread *thread) {
/* We must call Glib::Threads::Thread::join() in order to
 * correctly clean up the resource. */
if (thread) {
thread-join();
thread = NULL;
}
}

/* This function is called on a separate thread so as to avoid
 * blocking GTK+'s main loop.
 */
void blocking_operation(Glib::Dispatcher dispatcher) {
/* This simulates a blocking process */
sleep(10);

/* When the process is finished, we notify the GTK+ Main Loop by
 * using the dispatcher */
dispatcher();
}

/* This function is called on GTK+'s main loop via a
 * Glib::Dispatcher */
void blocking_operation_finished(const Glib::RefPtrGtk::TextBuffer tb,
 Glib::Threads::Thread *thread) {
cleanup_thread(thread);
tb-set_text(Operation finished.);
}

int main(int argc, char *argv[]) {
Glib::RefPtrGtk::Application app =
Gtk::Application::create(argc, argv, com.example);
Gtk::Window win;
Gtk::TextView tv;
Glib::RefPtrGtk::TextBuffer tb = tv.get_buffer();
Glib::Dispatcher dispatcher;
Glib::Threads::Thread *blocking_operation_thread = NULL;

/* Because I'm not using a class to encapsulate the above objects
 * and the methods (to keep it simple), I need to create
 * functors that are bound with these local variables.
 *
 * Note sigc::ref() is used here. Without it sigc::bind would try
 * to copy the dispatcher in this scope. We do not need to use
 * sigc::ref() on tb because RefPtr is a copyable pointer.
 */
sigc::slotvoid op_functor = sigc::bind(blocking_operation,
sigc::ref(dispatcher));

sigc::slotvoid op_finished_functor =
sigc::bind(blocking_operation_finished,
  tb,

sigc::ref(blocking_operation_thread));

/* The dispatcher will be used when the operation has finished.
 * Here we set the function the dispatcher will call on the main
 * thread -- a.k.a. GTK+'s Main Loop.
*/
dispatcher.connect(op_finished_functor);

/* Create a worker thread to perform the blocking_operation
 * function.
 */
blocking_operation_thread = Glib::Threads::Thread::create(op_functor);

/* Now set the text in the buffer.
 */
tb-set_text(Operation started.);

win.add(tv);
win.show_all();
app-run(win);

cleanup_thread(blocking_operation_thread);
return 0;
}
//== Example 2 End //

If one accepts the slight textual overhead of using a class, I have
provided another solution. This allows more straightforward use of
slots/functors, utilizing only sigc::mem_fun().

This example is 46 lines with no comments or whitespace.
//== Example 3 Begin //
#include gtkmm.h
#include unistd.h /* for sleep() */

class Example {
private:
Glib::RefPtrGtk::Application app;
Gtk::Windowwin;
Gtk::TextView  tv;
Glib::RefPtrGtk::TextBuffer  tb;
Glib::Dispatcher   dispatcher;
Glib::Threads::Thread *thread;

   /* This function is called on a separate thread so as to avoid
* blocking GTK+'s main loop.
*/
   void blocking_operation() {
/* This simulates a blocking process */
sleep(10);

/* When the process is finished, we notify the GTK+ Main Loop by
 * using the dispatcher */
dispatcher();
};

/* This function is called on GTK+'s main loop via a
 * 

Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James
Thank you Andrew.

  I misunderstood your first message and am looking at it more in depth
as well as your current post.

You bring up a very important clarification I should make from my
original post in this thread.  I should not have counted the comments as
part of the total number of lines.  Sometimes I post something, and have
an after though, but believe the general membership would see beyond my
error.

When excluding the important and very well documented comments of
Kjell's example it comes up to nearly have my original number.  The
lines of code is about 235.  Most of the confusion (for me) is the 11
widgets that, when I try to eliminate, breaks the code and I can't get
it to work.  I'm sure, eventually I'll figure it out, the same way if a
person looked at the code for LibreOffice, and spent a lot of time
analyzing and breaking it down.

When I first started programming and was able to output a Hello World,
I was happy.  It worked.  I made lots of changes and understood it.
When I performed my first I/O  it was just a minimum number of lines and
did a strictly limited task.  I was able to dissect it in one short
session, then start using it productively in my crude programs.

I'm trying to find this same strict focus with outputting and updating
the gtkmm gui (without user input).  If I can understand this, I'll have
a foundation of which I could build upon.

Kjell's example has everything I'm looking for, inclusive.  But with my
current understanding of gtkmm, it's too complex for me to be able to
use.  If all the widgets were eliminated and it just had a simple gui
window, it would be a bit easier for a beginner to work with.

At a glance it appears that you might have provided the needed solution
(possibly in your first message last week).  I apologize for missing
some of the gist, but I will spend a lot of time studying in minute
detail everything you have posted.  I appreciate your asking me to point
out what might be insufficient.

I also appreciate Kjell's invitation for the community (including me) to
comment on problems with his example.  I'm sure, for experts there would
hardly be any problems.  It was very easy to compile.  It has a lot
included.  However, for a novice, it's a bit overwhelming because it
includes so much.  A novice might have to keep everything intact to
ensure that the code will compile, then try to figure out where to put
his functions.  As I mentioned, in my case, if I remove the buttons and
progress bars, it becomes broken and I have to start back over with the
full code and try a different approach.

I would like to apologize to the community for being so new and using so
many words to explain my problem.  But if I use a minimum amount of
words, someone might spend hours trying to help, but might come up with
something that doesn't address the problem.  So I' trying to make the
problem clear, so that whatever time and energy anyone applies would
more likely answer the question.

Thanks!

-- L. James

-- 
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames


On Fri, 2013-08-09 at 23:13 -0700, Andrew Potter wrote:

 Mr. James,
 This reply has 3 examples. The last time I sent you a complete
 solution you never indicated how it was insufficient, so please be
 sure read this entire message.
 
 The minimum amount of lines to use a TextView:
 
 //== Example 1 Begin //
 #include gtkmm.h
 
 int main(int argc, char *argv[]) {
 Glib::RefPtrGtk::Application app =
 Gtk::Application::create(argc, argv, com.example);
 Gtk::Window win;
 Gtk::TextView tv;
 
 tv.get_buffer()-set_text(Hello world);
 win.add(tv);
 win.show_all();
 app-run(win);
 return 0;
 }
 //== Example 1 End //


___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James
Thanks you plenty, Andrew for giving so much consideration to my
question.  I'm really grateful for the generous comments and white
spaces for clarity.  I should have run this line on Kjell's code before
making a reference to 400 lines:

// cli command begin
cat * | egrep -v ^\s+\*|^$|^/|^\s+/ | wc
// cli command end

Without the comments and white space, I'd be substantially more lost.

At present your presentation is extremely clear and takes me far into
resolution of my immediate hurtle.

It compiles and works perfectly.

I have a few more questions of which I'll try to organize and be clear
when I post them.  Some of them might be resolved by my dissecting what
you've already posted with your clear documentation.

By the way, one of the questions is, the significants of the
com.example parameter of the Gtk::Application entry.  Does the
application use that information somewhere?  When programing the
Android, similar information is used for creating a default storage
space.

My other questions will relate to my effort to create a reusable
gprint function that I can run as a gui counter part of the console
cout.

The overhead doesn't matter. Just as long as I can have a one or two
liner in my function that will resemble: 

gprint(This is a new line of text);

That will either append or replace the text in the current gui window.
It might already be covered in the well documented code you've already
shared.  Hopefully I'll be able to at least understand what you've
already shared well enough to get the ball substantially rolling.

And oh yea, your example #1 was overwhelmingly clear, for a beginner.
Maybe the gtkmm maintainers will consider using something like that for
one of the beginner's hello world examples.  I believe placing the
hello world text on a button rather than some type of text screen
leaves some gaps that takes a while to fill.  It did in my case.

By the way, I hope the gtkmm maintainers appreciate my input.  I looked
at a lot of gui projects for C++ before choosing gtkmm.  I felt that I
had chose the best documented and supported solution.

The documentation is incredible!  It's just that some of it is
immediately over my head.  Looking at how all the additional widgets
falls into play is another lesson.  I'm sure once I'm able to fully
grasp the use of a single widget (in this case, the textview), the other
examples will soon be a cinch to understand.

Thanks!

-- L. James

-- 
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James
I may be able to eventually figure out how to do it from your example,
but at present it doesn't appear to have the ability to append text,
except for an initial text and one addition.

I'm trying to be able to arbitrarily update the text numerous times
(just like you would with cout).

I thought the dispatcher() function would work reusable like the
gprint() function I'm trying to create.  It appears to work correctly
the first time.

The other updates doesn't occur when the dispatcher() function is
called.  The gui window becomes non responsive and dimmed until all the
functions are completed, then everything is showed at once.  The window
at the end of the operation becomes a normal gui.

Kjell's example works exactly as intended, except that it has many
widgets and I can't figure out how to remove the widgets without
breaking the code.  Also it requires a clicking of a button to start.

I realize that, everything that a person needs is included in his
example.  My problem is being able to isolate a basic screen and an
update.

I know that I'll eventually understand it, and I'd be able to break it
down for anyone else that might have problems with it, and reuse the
many components in various applications.

I realize how easy it would be for you and other experts to use his
example.  But I can't figure out where to put my function and output a
single line to the gui, then perform a followup after some operations.

I also appreciate the your reference to how complicated this task is.
Hopefully I can contribute to making something complicated, easy for the
next person.

I added my example, using your code to demonstrate the problem that I'm
having.  I'm sure I'm misusing the dispatcher() function.  But I don't
see any other way to update the gui from your example.

Thanks again for your contribution and input!

// Code begin
//
--
#include gtkmm.h
#include unistd.h /* for sleep() */
#include iostream

using namespace std;

class Example {

string textdata = uninitilzed;

private:
Glib::RefPtrGtk::Application app;
Gtk::Windowwin;
Gtk::TextView  tv;
Glib::RefPtrGtk::TextBuffer  tb;
Glib::Dispatcher   dispatcher;
Glib::Threads::Thread *thread;

   /* This function is called on a separate thread so as to avoid
* blocking GTK+'s main loop.
*/
   void blocking_operation() {
/* This simulates a blocking process */
sleep(5);

textdata += First function is complete.\n;

/* When the process is finished, we notify the GTK+ Main Loop
by
 * using the dispatcher */
dispatcher();

sleep(5);
textdata += Second function is completed.\n;
dispatcher();

sleep(5);
textdata += Third function is completed.\n;
dispatcher();

sleep(5);
textdata += Fourth function is completed.\n;
textdata += This next funtion may take up to three hours to
complete.\n;
dispatcher();

sleep(60);
textdata += Fifth function is completed.\n;
dispatcher();
   };

/* This function is called on GTK+'s main loop via a
 * Glib::Dispatcher */
void blocking_operation_finished() {
cleanup_thread();
tb-set_text(textdata);
};

void cleanup_thread() {
/* We must call Glib::Threads::Thread::join() in order to
 * correctly clean up the resource. */
if (thread) {
thread-join();
thread = NULL;
}
}

public:
~Example() {
/* This will prevent the Window from being closed while
 * the blocking operation is ongoing. */
cleanup_thread();
}

Example(int argc, char *argv[]) : app(Gtk::Application::create(argc,
argv, com.example)), tb(tv.get_buffer()), thread(NULL)
{
/* Create a slot (a.k.a. functor) to the
 * blocking_operation_finished() member function for the
 * dispatcher to execute.
 */
sigc::slotvoid op_finished_functor = sigc::mem_fun(this,
Example::blocking_operation_finished);

/* The dispatcher will be used when the operation has finished.
 * Here we set the function the dispatcher will call on the
main
 * thread -- a.k.a. GTK+'s Main Loop.
 */
dispatcher.connect(op_finished_functor);

/* Now set the text in the buffer.
 */
textdata = Starting application.\n;
tb-set_text(textdata);

win.add(tv);
win.show_all();
}

void run() {
/* Create a slot to the blocking_operation() member function
 * to pass to Glib::Threads::Thread::create().
 */
sigc::slotvoid op_functor = sigc::mem_fun(this,
Example::blocking_operation);

/* Create a worker thread to perform the blocking_operation
 * function.
 */
thread = 

Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread Chris Vine
On Sat, 10 Aug 2013 05:43:42 -0400
L. D. James lja...@apollo3.com wrote:
 When I first started programming and was able to output a Hello
 World, I was happy.  It worked.  I made lots of changes and
 understood it. When I performed my first I/O  it was just a minimum
 number of lines and did a strictly limited task.  I was able to
 dissect it in one short session, then start using it productively in
 my crude programs.
 
 I'm trying to find this same strict focus with outputting and updating
 the gtkmm gui (without user input).  If I can understand this, I'll
 have a foundation of which I could build upon.

The point you may not understand is that you would rarely if ever want
to do this in a simple real-world application, and particularly where
your simple application is a learning exercise about using GTK+. GTK+
is, like almost all other GUI toolkits, event driven, and runs in a main
loop. Therefore, if text arrives which you want to put in a widget, it
would normally arrive as an event.  If you are monitoring I/O, you
would use Glib::signal_io().connect() to connect a file descriptor or
Glib::IOChannel object to the main loop. Similar convenience functions
are available for timeouts and idle handlers.

I would strongly advise you not to get involved in using threads until
you have more programming experience.

Chris
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James
Thanks for the advise, Chris

I already have a lot of applications of which I hope to put into place
for my clients who see a monster when they see a text screen.

Many of the task are very simple task, such as connecting to a VPN and
giving a status of each step, so that if any component failed, or got
stuck, the client could see it and not be turned off by seeing the text
screen.

I try to get people not to be so turned off by the text screen, but in
this world, they are.

Also, I'm making some of the task as launchers from the Ubuntu Unity
button.  The console screen doesn't look appealing, even to me.  To many
people (not to me of course, because I almost always work with a console
terminal and do most of my work remotely) when they see a console screen
that think that is evidence that something has crashed, or something bad
is happening.

I'm taking your advise, and had begun doing a lot of studying before I
starting asking my questions and asking for help.  I know that I could
eventually figure all this out without help.  But it'd take me years,
whereas I was hoping that there might be some users of this mailing
list, such as Alan and Andrew that might not mind parting with some of
their experience and helping me over some of my hurtles.

I don't mean to aggravate the group with my questions.  I assure you, I
won't be novice in this matter for long.  I'm a very fast learner and at
present have some gaps.

In my research some new users have been given the opposite advice of
what you had suggested to me.  Some users have been told to study gtkmm
and become familiar with this interface which had done a lot of work
with the lower level of gtk and gtk++.  They might waste a lot of time
trying to reinvent the wheel
( http://stackoverflow.com/questions/3448937/class-extending-gtkwindow )
for something already provided if they try to do it with gtk instead of
learning gtkmm.

Of course, you may be right, in that gtkmm has not taken into account
that a person might want to simply update the gui.

I believe there is a need in this capacity.  Kjell mention in his
message that, the need is there, and the solution is provided, but
didn't have any examples.  He has started to fill the void.

I already mentioned that I debated whether to learn gtkmm or to go a
different direction.  I even considered as you just suggested in working
with gtk instead of gtkmm, but took the advise of another expert to
learn how to use the gtkmm interface, rather than doing everything from
a low level and reinventing the wheel.

I can tell from Kjell's message that what I'm trying to do is already
implemented in gtkmm.  At present using it, just isn't all that clear.
I hope to contribute to the group by assisting in helping things to be
clearer, and to help close gaps that might exist.

I can already easily update the console with a status without user
input.  I believe there is also merit in updating agui window without
user input, of which, I appreciate the few people who have taking the
time to understand the problem and investigated it.

As far as realworld applications, most applications have some element of
processing and outputting a status to the user without the user having
to sit at the concole and constantly click buttons.  I really appreciate
your input and suggestions.  But I believe you're misunderstanding the
question.  I realize buttons and user input is an important part of
applications.  However, at present, I would just like to be able to
output notifications to my clients into a gui window without my
application having to be hung until they come to the computer and click
a button.  The purpose of what I'm trying to do is allow the user to
know at which stage the application has progressed, and to be able to
report to me any messages, errors status updates that I present.  As far
as the VPN connection, if my program is waiting for an internet
connection, it will state that.  When it has the connection, without the
user having to come back and tell the program to continue, it will just
update, internet connection established, the remote host is currently
off line... will try again in 5 minutes.  The  present console program
eventually says, vpn connection established now configuring the local
routing.

I have many applications (or c++ routines) to do things such as that.
They all output to a black screen.  They frighten my customers.  I hope
to find a simple way of outputting the status to a friendly gui window.

I don't mean to sound ungrateful with my reply, but I'm hoping that I'm
clarifying what I'm trying to do, and that it does have some merit.

-- L. James

-- 
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames

On Sat, 2013-08-10 at 13:54 +0100, Chris Vine wrote:

 On Sat, 10 Aug 2013 05:43:42 -0400
 L. D. James lja...@apollo3.com wrote:
  When I first started programming and was able to output a Hello
  World, I was happy.  It worked.  I made lots of changes and
  understood it. When I performed my first 

Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread Chris Vine
On Sat, 10 Aug 2013 09:32:58 -0400
L. D. James lja...@apollo3.com wrote:
[snip]
 As far as realworld applications, most applications have some element
 of processing and outputting a status to the user without the user
 having to sit at the concole and constantly click buttons.  I really
 appreciate your input and suggestions.  But I believe you're
 misunderstanding the question.  I realize buttons and user input is
 an important part of applications.  However, at present, I would just
 like to be able to output notifications to my clients into a gui
 window without my application having to be hung until they come to
 the computer and click a button.  The purpose of what I'm trying to
 do is allow the user to know at which stage the application has
 progressed, and to be able to report to me any messages, errors
 status updates that I present.  As far as the VPN connection, if my
 program is waiting for an internet connection, it will state that.
 When it has the connection, without the user having to come back and
 tell the program to continue, it will just update, internet
 connection established, the remote host is currently off line... will
 try again in 5 minutes.  The  present console program eventually
 says, vpn connection established now configuring the local routing.
 
 I have many applications (or c++ routines) to do things such as that.
 They all output to a black screen.  They frighten my customers.  I
 hope to find a simple way of outputting the status to a friendly gui
 window.
 
 I don't mean to sound ungrateful with my reply, but I'm hoping that
 I'm clarifying what I'm trying to do, and that it does have some
 merit.

Your posts are no doubt highly meritorious but I am afraid they are not
offering much clarification.  You would probably make your point better
if you shortened your posts by roughly an order of magnitude.  However,
after cutting through the dense undergrowth, I still think you have
failed to understand how programs using event loops work.  If the
program is not just running a single batch of instructions, it has to
have a loop in there somewhere, which is blocking until there is
something to process.  The simplest loop for your console program would
involve blocking on select() or poll(), for which purpose presumably
you must have a file descriptor to poll on.  In that case, as I said,
you can do the same with Glib::signal_io().connect().  Or maybe you are
polling using timeouts, in which case the equivalent for gtkmm is
Glib::signal_timeout().connect().

Why not get to the heart of the matter, and post a short compilable
console program, cut down from the ones which you appear to have written
for monitoring VPNs, but of no more than 50 lines, and we can tell you
how to do the same using a graphical interface.

Chris
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James
On Sat, 2013-08-10 at 16:45 +0100, Chris Vine wrote:


 Your posts are no doubt highly meritorious but I am afraid they are not
 offering much clarification.  You would probably make your point better
 if you shortened your posts by roughly an order of magnitude.  However,
 after cutting through the dense undergrowth, I still think you have
 failed to understand how programs using event loops work.  If the
 program is not just running a single batch of instructions, it has to
 have a loop in there somewhere, which is blocking until there is
 something to process.  The simplest loop for your console program would
 involve blocking on select() or poll(), for which purpose presumably
 you must have a file descriptor to poll on.  In that case, as I said,
 you can do the same with Glib::signal_io().connect().  Or maybe you are
 polling using timeouts, in which case the equivalent for gtkmm is
 Glib::signal_timeout().connect().
 
 Why not get to the heart of the matter, and post a short compilable
 console program, cut down from the ones which you appear to have written
 for monitoring VPNs, but of no more than 50 lines, and we can tell you
 how to do the same using a graphical interface.
 
 Chris


I'll accept the admonishment.  I'm sorry for the verbose description.
It appears that you're starting to get the gist.  I appreciate your
asking me to expound with an example.

The VPN application currently have 500 lines.  I'll strip it down to 50,
making sure it retains functionality and post it.

One of the reasons I didn't post it before, but posted sleep(10) to
represent the application was doing something, because the program is
designed to make changes to the system.  But, I'm sure I'll be able to
comment and have such a flow that you might be able to easily follow it
just by looking at it, or, on your own, comment out the parts that makes
changes.

Thanks!

-- L. James

-- 
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread Chris Vine
On Sat, 10 Aug 2013 12:16:16 -0400
L. D. James lja...@apollo3.com wrote:
[snip]
 The VPN application currently have 500 lines.  I'll strip it down to
 50, making sure it retains functionality and post it.
 
 One of the reasons I didn't post it before, but posted sleep(10) to
 represent the application was doing something, because the program is
 designed to make changes to the system.  But, I'm sure I'll be able to
 comment and have such a flow that you might be able to easily follow
 it just by looking at it, or, on your own, comment out the parts that
 makes changes.

If an outline of your code just consists of:

void check_stuff() {
  if (vpn_connections_changed()) std::cout  XXX changed\n;
}

int main(int argc, char* argv[]) {
  for (;;) {
sleep(10);
check_stuff();
  }
  return 0;
}

Then in gtkmm this just becomes:

bool check_stuff() {
  if (vpn_connections_changed()) std::cout  XXX changed\n;
  return true;
}

int main(int argc, char* argv[]) {
  Gtk::Main app(argc, argv);
  Glib::signal_timeout().connect_seconds(sigc::ptr_fun(check_stuff), 10);
  app.run();
  return 0;
}

You can go from there and add your graphical interface to check_stuff()
in place of the call to std::cout.  You might, for example, want to
display a Gtk::MessageDialog object.  With gtkmm-3.0, you might want
to use Gtk::Application instead of Gtk::Main.  But first things first.

Chris
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread Andrew Potter
dispatcher() causes the function blocking_operation_finished() to be
called, which in turn calls Glib::Threads::Thread::join(). join() will
block the GTK+ main loop until the thread has completely finished
(i.e. blocking_operation() has returned).

Calling dispatcher() more than once means that
blocking_operation_finished() will be called more than once. I hope
you can understand why that is wrong.

Here is the next step in our example series. I have chosen to abstract
the ability to send parameters a function on the main thread through
the use of the CallbackDispatcher class. Its usage is simple: create a
functor that accepts zero arguments and pass it to send(). That
functor will be executed on the main loop.

A zero argument functor may be created from any function by using sigc::bind.

I have also chosen to use a Gtk::Label for this example, so as to
sidestep the issue of bug 495762.

Using a custom wrapper around Glib::Dispatcher to teach a newbie is,
perhaps, bad etiquette. But the utility of this wrapper in sending
progress back to the main loop has been so great in my experience that
I can't resist.
//== Example 4 Begin //
#include gtkmm.h
#include unistd.h /* for sleep() */
#include queue

class CallbackDispatcher {
public:
CallbackDispatcher() {
dispatcher.connect(sigc::mem_fun(this,
CallbackDispatcher::on_dispatch));
}

typedef sigc::slotvoid Message;
void send(Message msg) {
Glib::Threads::Mutex::Lock lock(mutex);
queue.push(msg);
dispatcher();
}

private:
/* CallbackDispatcher may not be copied, so we must hide these
 * constructors */
CallbackDispatcher(const CallbackDispatcher);
CallbackDispatcher operator=(const CallbackDispatcher);

Glib::Threads::Mutex mutex;
std::queueMessage queue;
Glib::Dispatcher dispatcher;

void on_dispatch() {
Glib::Threads::Mutex::Lock lock(mutex);
while (!queue.empty()) {
queue.front()();
queue.pop();
}
}
};

class Example {
private:
Glib::RefPtrGtk::Application app;
Gtk::Windowwin;
Gtk::Label label;
CallbackDispatcher callback_dispatcher;
Glib::Threads::Thread *thread;

void report_progress(const Glib::ustring str) {
callback_dispatcher.send(sigc::bind(sigc::mem_fun(label,
Gtk::Label::set_text), str));
}

   /* This function is called on a separate thread so as to avoid
* blocking GTK+'s main loop.
*/
void blocking_operation() {
/* This simulates a blocking process */
sleep(5);
report_progress(5% complete.);

sleep(5);
report_progress(15% complete.);

sleep(5);
report_progress(35% complete.);

sleep(5);
report_progress(55% complete.);

sleep(5);
report_progress(75% complete.);

sleep(5);
report_progress(95% complete.);

sleep(5);
report_progress(100% complete.);

/* When the process is finished, we notify the GTK+ Main Loop by
 * using the dispatcher */
callback_dispatcher.send(sigc::mem_fun(this,
Example::blocking_operation_finished));
};

/* This function is called on GTK+'s main loop via a
 * Glib::Dispatcher */
void blocking_operation_finished() {
cleanup_thread();
label.set_text(Operation finished.);
};

void cleanup_thread() {
/* We must call Glib::Threads::Thread::join() in order to
 * correctly clean up the resource. */
if (thread) {
thread-join();
thread = NULL;
}
}

public:
~Example() {
/* This will prevent the Window from being closed while
 * the blocking operation is ongoing. */
cleanup_thread();
}

Example(int argc, char *argv[]) :
app(Gtk::Application::create(argc, argv, com.example)),
label(),
thread(NULL)
{
win.add(label);
win.show_all();
}

void run() {
/* Create a slot to the blocking_operation() member function
 * to pass to Glib::Threads::Thread::create().
 */
sigc::slotvoid op_functor = sigc::mem_fun(this,
Example::blocking_operation);

/* Create a worker thread to perform the blocking_operation
 * function.
 */
thread = Glib::Threads::Thread::create(op_functor);

/* Now set the text in the buffer.
 */
label.set_text(Operation started.);

app-run(win);
}
};

int main(int argc, char *argv[]) {
Example example(argc, argv);

example.run();
return 0;
}
//== Example 4 End //


On Sat, Aug 10, 2013 at 5:39 AM, L. D. James lja...@apollo3.com wrote:
 I may be able to eventually figure out how to do it from your example, but
 at present it doesn't appear to have the ability to append text, except for
 an initial text and one addition.

Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James

On 08/10/2013 11:45 AM, Chris Vine wrote:

Your posts are no doubt highly meritorious but I am afraid they are not
offering much clarification.  You would probably make your point better
if you shortened your posts by roughly an order of magnitude.  However,
after cutting through the dense undergrowth, I still think you have
failed to understand how programs using event loops work.  If the
program is not just running a single batch of instructions, it has to
have a loop in there somewhere, which is blocking until there is
something to process.  The simplest loop for your console program would
involve blocking on select() or poll(), for which purpose presumably
you must have a file descriptor to poll on.  In that case, as I said,
you can do the same with Glib::signal_io().connect().  Or maybe you are
polling using timeouts, in which case the equivalent for gtkmm is
Glib::signal_timeout().connect().
Chris, thanks again for your interest in my question.  I apologize for 
the delayed response, as I was on a support call for most of the day.  
When I got back I trimmed down 500 lines of code to the example below.


This is 48 lines of my vpn connection routine. It's 48 out of the 500 
line application. In those 48 lines I have 4 lines outputting to the 
console. I would like for those lines to output to a gui window.


Those 4 lines are just some of the actually 25 lines of status that will 
be output in the course of running the application. While it's running 
and checking the connection it outputs either starts * or dots . at 
10 second interval while it checks some of the file and connection status.



// code begin
// -
#include iostream
#include fstream
#include unistd.h
#include string
using namespace std;
int main(int argc, char* argv[]) {
string ret;
string server;
string command;
string runit(string c);
setuid(0);
server = argv[1];
string peerentry = /etc/ppp/peers/ + server;
command = ls  + peerentry;
ret = runit(command);
if (ret != peerentry){
cout  Problems locating server:   server  endl; // 
console out

return 1;
}
string filetest = /var/run/ppp- + server + .pid;
ifstream myfile(filetest.c_str());

if (myfile.is_open()){
cout  Connection is in effect  endl; // console out
myfile.close();
}
else{
cout  Connecting to...  server  endl; // console out
command = pppd call  + server;
ret = runit(command);
cout  Results: [  ret  ]  endl; // console out
}
return 0;
}
string runit(std::string c){
string lret = ;
c +=  21;
FILE *in;
char buff[512];
if (!(in = popen(c.c_str(), r))){
return lret;
}
while (fgets(buff, sizeof(buff), in) != NULL){
lret += buff;
}
pclose(in);
return lret;
}
// -
// code end

-- L. James

--
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James
Thanks, Andrew.  I'll study and compile your example and comment on if
it's the gist of what I'm trying to accomplish.

Looking at it, it appears like it will work.  However, I'm not trying to
send progress statistics, I'm just trying to send general information.
Some of my programs sorts and index, and archives email messages.  It
may send a message to the console that there are currently 1000 emails
about to be sorted.  Then it's cross reference the headers with messages
addresses in the users' address book.  It'll output to the console that
there are 500 email addresses that are not in the address book and sort
them into a separate area.  These are all messages to a black console.

Many of my customers are used to seeing the black screen.  I'm just want
to take my 10's of programs and have many of them output the text to a
graphics screen rather than the console screen.

I will find it convenient to create a function call gprint().  Where I
have cout ether replace the cout with gprint or use both, but the
gprint() will just update a gui with a message that currently goes to
a black screen.

I apologize for repeating this so much.  I have read numerous times the
code of conduct for this forum.  I'm trying to comply and not to
aggravate the membership with repetition and verbose messages.  But most
of the comments I get gives me the impression that the members are
misunderstanding what I'm looking for.

Just like gtkmm is a convenient wrapper for gtk++, I hope to make a
gprint() routine to be a wapper for however many lines it takes to
create a gui window and be able to run a one or two liner to please a
new message to that gui window.

At a glance it appears that the code you have below might have the gist,
even though it's referencing percentages of progress instead of regular
text output informing the user what the application is currently doing,
and what it might do next, or informing the user of any errors or
problems it might be encountering.

I really apologize for the many words to try to be clear.  I just posted
an example of one of my C++ applications.  I have done it with Java and
might post a Java application that perfectly fits the bill (as for as
having a window and sending updates to that window).  The problem with
the Java, is that you can't set the suid bit for some of the routines
that needs to be run as root.

I was doing that with a C++ wrapper to call the Java program.  But now,
I'm trying to do it all in C++ with gtkmm.

Once I develop the gprint() function, I'm sure this will totally make
things clear.  I'm sure that many will find it a convenient resource.

-- L. James

-- 
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames

On Sat, 2013-08-10 at 12:23 -0700, Andrew Potter wrote:

 dispatcher() causes the function blocking_operation_finished() to be
 called, which in turn calls Glib::Threads::Thread::join(). join() will
 block the GTK+ main loop until the thread has completely finished
 (i.e. blocking_operation() has returned).
 
 Calling dispatcher() more than once means that
 blocking_operation_finished() will be called more than once. I hope
 you can understand why that is wrong.
 
 Here is the next step in our example series. I have chosen to abstract
 the ability to send parameters a function on the main thread through
 the use of the CallbackDispatcher class. Its usage is simple: create a
 functor that accepts zero arguments and pass it to send(). That
 functor will be executed on the main loop.
 
 A zero argument functor may be created from any function by using sigc::bind.
 
 I have also chosen to use a Gtk::Label for this example, so as to
 sidestep the issue of bug 495762.
 
 Using a custom wrapper around Glib::Dispatcher to teach a newbie is,
 perhaps, bad etiquette. But the utility of this wrapper in sending
 progress back to the main loop has been so great in my experience that
 I can't resist.
 //== Example 4 Begin //
 #include gtkmm.h
 #include unistd.h /* for sleep() */
 #include queue
 
 class CallbackDispatcher {
 public:
 CallbackDispatcher() {
 dispatcher.connect(sigc::mem_fun(this,
 CallbackDispatcher::on_dispatch));
 }
 
 typedef sigc::slotvoid Message;
 void send(Message msg) {
 Glib::Threads::Mutex::Lock lock(mutex);
 queue.push(msg);
 dispatcher();
 }
 
 private:
 /* CallbackDispatcher may not be copied, so we must hide these
  * constructors */
 CallbackDispatcher(const CallbackDispatcher);
 CallbackDispatcher operator=(const CallbackDispatcher);
 
 Glib::Threads::Mutex mutex;
 std::queueMessage queue;
 Glib::Dispatcher dispatcher;
 
 void on_dispatch() {
 Glib::Threads::Mutex::Lock lock(mutex);
 while (!queue.empty()) {
 queue.front()();
 queue.pop();
 }
 }
 };
 
 class Example {
 private:
 Glib::RefPtrGtk::Application app;
 Gtk::Windowwin;
 Gtk::Label   

Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread Chris Vine
On Sat, 10 Aug 2013 17:53:41 -0400
L. D. James lja...@apollo3.com wrote:
[snip]
 Chris, thanks again for your interest in my question.  I apologize
 for the delayed response, as I was on a support call for most of the
 day. When I got back I trimmed down 500 lines of code to the example
 below.
 
 This is 48 lines of my vpn connection routine. It's 48 out of the 500 
 line application. In those 48 lines I have 4 lines outputting to the 
 console. I would like for those lines to output to a gui window.
 
 Those 4 lines are just some of the actually 25 lines of status that
 will be output in the course of running the application. While it's
 running and checking the connection it outputs either starts * or
 dots . at 10 second interval while it checks some of the file and
 connection status.
 
 
 // code begin
 // -
 #include iostream
 #include fstream
 #include unistd.h
 #include string
 using namespace std;
 int main(int argc, char* argv[]) {
  string ret;
  string server;
  string command;
  string runit(string c);
  setuid(0);
  server = argv[1];
  string peerentry = /etc/ppp/peers/ + server;
  command = ls  + peerentry;
  ret = runit(command);
  if (ret != peerentry){
  cout  Problems locating server:   server  endl; // 
 console out
  return 1;
  }
  string filetest = /var/run/ppp- + server + .pid;
  ifstream myfile(filetest.c_str());
 
  if (myfile.is_open()){
  cout  Connection is in effect  endl; // console out
  myfile.close();
  }
  else{
  cout  Connecting to...  server  endl; // console out
  command = pppd call  + server;
  ret = runit(command);
  cout  Results: [  ret  ]  endl; // console out
  }
  return 0;
 }
 string runit(std::string c){
  string lret = ;
  c +=  21;
  FILE *in;
  char buff[512];
  if (!(in = popen(c.c_str(), r))){
  return lret;
  }
  while (fgets(buff, sizeof(buff), in) != NULL){
  lret += buff;
  }
  pclose(in);
  return lret;
 }
 // -
 // code end

This appears to be just a batch job calling popen() which brings up a
ppp connection. There is no program loop anywhere and the while
loop for fgets() in runit() will block until EOF is reached, which
equates to the call to pppd ending and the process in which it is
running closing its stdout. Presumably you run this as a cron job, or
something like that? Or, since you say, while it's running and
checking the connection it outputs either starts '*' or dots '.' at 10
second interval while it checks some of the file and connection status,
possibly you have excised the loop logic, which is the interesting part
for present purposes. (As it happens, it will not compile because the
prototype for runit() is not in namespace scope, but that is no doubt
just a matter of transcription.)

To call up an executable (in this case pppd) in this kind of usage
using glib you would normally use Glib::spawn_async_with_pipes() and
connect to the standard_output and standard_error file descriptors with
Glib::signal_io().connect(). The problem you have got here though is
that you call setuid(0) on a binary which presumably has its suid bit
set in order to launch pppd. You should definitely not do that directly
with a GTK+ program.  You would need to have a small wrapper with suid
set which calls up pppd, which is launched by your GTK+ program using
Glib::spawn_async_with_pipes().  (Yuck.)

As it happens, if you want a short cut for a batch job like this which
provides a GTK+ user interface, I would consider a shell script and
zenity, which is what zenity was intended for.  A google search will
tell you more. However you would still need to circumvent your setuid
problem.

Chris
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James

On 08/10/2013 07:09 PM, Chris Vine wrote:
This appears to be just a batch job calling popen() which brings up a 
ppp connection. There is no program loop anywhere and the while loop 
for fgets() in runit() will block until EOF is reached, which equates 
to the call to pppd ending and the process in which it is running 
closing its stdout. Presumably you run this as a cron job, or 
something like that? Or, since you say, while it's running and 
checking the connection it outputs either starts '*' or dots '.' at 10 
second interval while it checks some of the file and connection 
status, possibly you have excised the loop logic, which is the 
interesting part for present purposes. (As it happens, it will not 
compile because the prototype for runit() is not in namespace scope, 
but that is no doubt just a matter of transcription.) To call up an 
executable (in this case pppd) in this kind of usage using glib you 
would normally use Glib::spawn_async_with_pipes() and connect to the 
standard_output and standard_error file descriptors with 
Glib::signal_io().connect(). The problem you have got here though is 
that you call setuid(0) on a binary which presumably has its suid bit 
set in order to launch pppd. You should definitely not do that 
directly with a GTK+ program. You would need to have a small wrapper 
with suid set which calls up pppd, which is launched by your GTK+ 
program using Glib::spawn_async_with_pipes(). (Yuck.) As it happens, 
if you want a short cut for a batch job like this which provides a 
GTK+ user interface, I would consider a shell script and zenity, which 
is what zenity was intended for. A google search will tell you more. 
However you would still need to circumvent your setuid problem. Chris 


Hi, Chris.  I stripped down a 500 line C++ program and included some 
system calls to give you and example of my many C++ programs.  Many C++ 
programs use calls to the system shell.  I can tell that happening with 
a number of driver installations.


This application would not work as a bash script.  I mentioned to you 
that you can not set the suid bit on a bash script.


I'm familiar with cron jobs, and have no problems with cronjobs.  In 
fact some of my applications are run by cron.


The particular VPN connection application is run currently added to the 
Ubuntu dash and shows a black screen for the status when it's run.


By the way, there are gui applications for batch files, perl files and 
just about any other programming concept.


I appreciate your interest and your questions and suggestions.  I 
understand that I don't have to use or learn gtkmm.  But I hope you 
don't mind my interest in the facility.


Some of my applications do not use any system calls.  Some of them use 
some system calls.  But I would like for most of them to output to a gui 
window where than a console.  I understand how complicated you think 
this will be.  But it can be done with C++ just as with just about any 
programming application.


By the way, the program does compile.  I've already started to add the 
gui interface.  I did it with the gtk label with the help of Alan.  I 
posted the example in a different thread.  I ran into problems when I 
tried to change the label widget into a textview widget because I was 
having problems understanding the full gist of the gtkmm tools.  When 
Kjell posted his resolution, I saw the light.  So I started this thread 
on trying to break down Kjell's program into components (namely to 
eliminated the unneeded widgets).


I'm getting there with some of the in-between the line suggestions from 
this new thread.  I'm starting to understand more and more how to use 
gtkmm, of which I'm trying to do.  I really don't think it's as 
complicated and some users are suggesting.  I believe it's just a matter 
of getting a grip of a few vague concepts.


While I'm having problems just sending text to a window, you're 
suggesting that I dive figure and use gtkmm for my other calls.  I might 
get to that at some time.  But at present, I just want to use gtkmm to 
output to a gui screen instead of a black screen.


-- L. James

--
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


compiler error

2013-08-10 Thread Kemin Zhou bmsid=00337162
I am trying to compiler gtkmm2.99,
Some some packages, they don't like gtk3.*

I am not sure this is because that I am using a newer compiler or not:


cal/include/c++/4.8.1 -MT event.lo -MD -MP -MF .deps/event.Tpo -c -o
event.lo event.cc
libtool: compile:  g++ -DHAVE_CONFIG_H -I.. -I../.. -DG_LOG_DOMAIN=
\gdkmm\ -DGDKMM_BUILD=1 -pthread -pthread
-I/usr/local/include/giomm-2.4 -I/usr/local/lib/giomm-2.4/include
-I/usr/local/include/glibmm-2.4 -I/usr/local/lib/glibmm-2.4/include
-I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include
-I/usr/local/include/sigc++-2.0 -I/usr/local/lib/sigc++-2.0/include
-I/usr/local/include/pangomm-1.4 -I/usr/local/lib/pangomm-1.4/include
-I/usr/local/include/cairomm-1.0 -I/usr/local/lib/cairomm-1.0/include
-I/usr/local/include/pango-1.0 -I/usr/local/include/cairo
-I/usr/local/include -I/usr/local/include/freetype2
-I/usr/local/include/gtk-3.0 -I/usr/local/include/atk-1.0
-I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/gdk-pixbuf-2.0
-I/usr/local/include/harfbuzz -I/usr/include/pixman-1
-I/usr/include/libpng12 -I/usr/include/at-spi2-atk/2.0 -Wall
-I/usr/local/include/boost -I/usr/local/include/c++/4.8.1 -MT event.lo
-MD -MP -MF .deps/event.Tpo -c event.cc  -fPIC -DPIC -o .libs/event.o
event.cc: In static member function ‘static GType
Glib::ValueGdk::ExtensionMode::value_type()’:
event.cc:51:38: error: ‘gdk_extension_mode_get_type’ was not declared in
this scope
   return gdk_extension_mode_get_type();
  ^
event.cc:52:1: warning: control reaches end of non-void function
[-Wreturn-type]
 }

Kemin



___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread Chris Vine
On Sat, 10 Aug 2013 19:41:33 -0400
L. D. James lja...@apollo3.com wrote:
[snip]
 While I'm having problems just sending text to a window, you're 
 suggesting that I dive figure and use gtkmm for my other calls.  I
 might get to that at some time.  But at present, I just want to use
 gtkmm to output to a gui screen instead of a black screen.

You keep missing the point.  If you don't want to use zenity, as I said
use Glib::spawn_async_with_pipes() and Glib::signal_io().connect().
That is the correct way to do it.

Chris
___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list


Re: What is the minimum number of lines to update a gui window without user clicking a button

2013-08-10 Thread L. D. James
Thanks, Chris.  I may end up using Glib::spawn_async (but I it doesn't
appear to be a call for updating text to a gui window) and I may end up
using Glib::signal_io().connect()) to send text to the gui window.  This
is the first time i see these as ways of updating the gui.

Keep in mind that what I'm trying to do is develop a reusable function
that I have named, gprint().  I'm sure I'm just about close enough to
post a prototype by tomorrow.

Thanks again for all your contributions, and patient for my newness with
using a gtkmm widgets.

My only problem with Kjell's example if being able to remove the
unwanted ones.  My problem with Alan's solution (which worked perfect)
was changing it from label to textview (because of some gaps I was
having at the time).

I finally got it figured out how to change the widget from label to text
view, now I'm trying to implement the gprint() function.  I have it in
place, but it's not clean enough to post it for comments yet.

-- L. James

-- 
L. D. James
lja...@apollo3.com
www.apollo3.com/~ljames

On Sun, 2013-08-11 at 01:20 +0100, Chris Vine wrote:

 On Sat, 10 Aug 2013 19:41:33 -0400
 L. D. James lja...@apollo3.com wrote:
 [snip]
  While I'm having problems just sending text to a window, you're 
  suggesting that I dive figure and use gtkmm for my other calls.  I
  might get to that at some time.  But at present, I just want to use
  gtkmm to output to a gui screen instead of a black screen.
 
 You keep missing the point.  If you don't want to use zenity, as I said
 use Glib::spawn_async_with_pipes() and Glib::signal_io().connect().
 That is the correct way to do it.
 
 Chris


___
gtkmm-list mailing list
gtkmm-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtkmm-list