Re: How to update both the Console and the GTKMM gui window after running other functions



Hi, Andrew. I don' t understand what you mean about standard GUI design principals. But in Java (and possibly in Gtkmm) it's possible to have a gui window there. The buffer sits in the window. Changing the content of the string shouldn't have have interfere with the integrety of the gui window. With Java (the particular textarea widget, you just see what is in the text and can change the content of the text from anywhere. Changing the content if the text will be displayed.

I don't know how to explain it. But in most of my studies emphasis is usually placed on having concise and an easy flow program design. Since it only takes one to change the content of the buffer:

// Code begin
// -----------------------------

textArea.setText("This is printed in the gui window");

// -----------------------------
// Code end

I can't understand a reason to have to do anything different. You can use "textArea.setText(string text)" to have new text or "textArea.append(string text)" to append to it. It can't be simpler than that (in Java). It works and I use it all the time. There are many examples all over the internet of how to do this in Java.

I'll take all your suggestions and code examples for "gtkmm" into study for how to use "gtkmm" but as for as my Java example, I don't think those few lines violate any standard.

Variations of those two lines are repeated countless times with the Java experts giving support.

-- L. James

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

On 08/01/2013 12:54 PM, Andrew Potter wrote:
On Thu, Aug 1, 2013 at 7:24 AM, Jonas Platte <jonasplatte myopera com> wrote:
Am 01.08.2013 16:11, schrieb L. D. James:
// sample code begin
// -------------------------------------
String updatetext = "About to run a process that might take an hour... sit
back and wait...\n";
System.out.printl(updatetext);
textArea.append(updatetext);
int count = 0;
TimeUnit.SECONDS.sleep(3600); // Scanning all the local and network hard
drives for files larger than 1 gig
// Scanning all the local and network hard drives for files larger than 1
gig
updatetext = "The scan has completed with " << count << " files found";
System.out.println(updatetext);
textArea.append(updatetext);
// -------------------------------------
// sample code end
Your Java code appears to be broken according to standard GUI design
principals in that the GUI will not respond to events during your
blocking operation.

Here is the same broken code in C++:
#include <gtkmm.h>
#include <iostream>
#include <unistd.h>

void run_first(Gtk::Label& label) {
     label.set_text("Starting blocking operation");
     std::cout << "Starting blocking operation" << std::endl;
     sleep(5);
     label.set_text("The scan has completed");
     std::cout << "The scan has completed" << std::endl;
}

int main(int argc, char *argv[]) {
     Glib::RefPtr<Gtk::Application> app =
Gtk::Application::create(argc, argv, "com.example");
     Gtk::Window win;
     Gtk::Label label;
     Gtk::Button btn("Start");
     Gtk::Box box(Gtk::ORIENTATION_VERTICAL);
     box.add(label);
     box.add(btn);

     btn.signal_clicked().connect(sigc::bind(sigc::ptr_fun(&run_first),
sigc::ref(label)));
     label.set_text("Program started.");
     std::cout << "Program started." << std::endl;
     win.add(box);
     win.show_all();
     app->run(win);

     return 0;
}

Notice that it will not run as expected, the "Starting blocking
operation" text is never shown in the label because control is never
passed back to the main loop so that the text may be rendered and
drawn on screen. Here is a program that allows the "Starting blocking
operation" text to actually be painted, but it still incorrectly
blocks the main loop:
void run_second(Gtk::Label& label) {
     sleep(5);
     label.set_text("The scan has completed");
     std::cout << "The scan has completed" << std::endl;
}

void run_first(Gtk::Label& label) {
     label.set_text("Starting blocking operation");
     std::cout << "Starting blocking operation" << std::endl;
     Glib::signal_timeout().connect_seconds_once(sigc::bind(sigc::ptr_fun(&run_second),
sigc::ref(label)),1);
}

This is still, however, not correct program design. Blocking
operations should not be performed in the main loop. Glib provides a
wide host of facilities for asynchronous file and network I/O. If glib
does not provide sufficient facility for you, you may use threads to
perform blocking operations. However, you must keep in mind you may
not update the GUI from a separate thread.

Here is a complete example:
#include <gtkmm.h>
#include <iostream>
#include <unistd.h>

class MyClass
{
public:
     MyClass(Gtk::Label *label, Gtk::Button *button) : m_label(label),
m_button(button), m_thread(NULL) {
         m_dispatcher.connect(sigc::mem_fun(this,
&MyClass::blocking_operation_finished));
     };

     ~MyClass() {
         if (m_thread)
             m_thread->join();
     }

     void start_operation() {
         m_button->set_sensitive(false);
         m_label->set_text("Starting blocking operation");
         std::cout << "Starting blocking operation" << std::endl;
         m_thread = Glib::Threads::Thread::create(sigc::mem_fun(this,
&MyClass::blocking_operation));
     }

private:
     void blocking_operation() {
         sleep(5);
         m_dispatcher();
     };

     void blocking_operation_finished() {
         m_thread->join();
         m_thread = NULL;
         m_button->set_sensitive(true);
         m_label->set_text("The scan has completed");
         std::cout << "The scan has completed" << std::endl;
     }

     Gtk::Label *m_label;
     Gtk::Button *m_button;
     Glib::Threads::Thread *m_thread;
     Glib::Dispatcher m_dispatcher;
};

int main(int argc, char *argv[]) {
     Glib::RefPtr<Gtk::Application> app =
Gtk::Application::create(argc, argv, "com.example");
     Gtk::Window win;
     Gtk::Label label;
     Gtk::Button btn("Start");
     Gtk::Box box(Gtk::ORIENTATION_VERTICAL);
     MyClass myClass(&label, &btn);

     box.add(label);
     box.add(btn);
     btn.signal_clicked().connect(sigc::mem_fun(myClass,
&MyClass::start_operation));
     label.set_text("Program started.");
     std::cout << "Program started." << std::endl;
     win.add(box);
     win.show_all();
     app->run(win);

     return 0;
}

I strongly recommend you read the Gtkmm tutorial:
https://developer.gnome.org/gtkmm-tutorial/unstable/index.html
_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
https://mail.gnome.org/mailman/listinfo/gtkmm-list



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]