L. D. James
L. D. James

Reputation: 1719

How can you update the gtkmm gui screen from your c++ code after it is created

Can someone help to clear up the confusion of how to update a gui window without user input.

In other words, I would like to be able to output text to either or both the console our the gui window.

At present I can call the gui window (Window with a label for example) and output the initial text. However, the process doesn't return to my c++ code until the window closes. I'm trying to figure out how to (or where to have my code) for updating the gui screen before the gui window exits.

This is an example:

#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
    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;
    mylabeltext = "Showing the results of the functions and processing.";
    label.set_text(mylabeltext);

    return 0;
}

The last line of text is never printed to the console until the gui is exited. The last line of the mylabeltext is never printed to the label window.

What I'm trying to describe is how to keep the gtkmm window active while I run other routines in my c++ code and update the output to both the console and the gui window without closing the gui window to continue the c++ routines.

All the examples that I can find uses a button in the code. I have tested and experimented enough that I can update the gui screen after a button is pressed. However, I don't want to have to rely on the user for screen updates. I hope to be able to run disc scans and other functions and periodically update the screen so that the user can see the progress and know that the program is still working and not dead.

Some of the resources that I have studied in my attempts at understanding this include:

Upvotes: 0

Views: 3463

Answers (2)

L. D. James
L. D. James

Reputation: 1719

This is crude, but this is functional for what I was trying to do:

#include <gtkmm.h>
#include <iostream>

using namespace std;

class myLabel: public Gtk::Window
{
public:
    myLabel();
    virtual ~myLabel();

protected:
    Gtk::Label m_label;
    string labeltext;
    string newtext;
    void myprocess1();
};

myLabel::myLabel() :
        m_label()
{
    void myprocess1();

    set_title("Gtkmm Programming - C++");
    add(m_label);

    m_label.show();

    Glib::Thread::create(sigc::mem_fun(*this, &myLabel::myprocess1), true);
}

myLabel::~myLabel()
{
}

void myLabel::myprocess1()
{
    labeltext = "About to preform a number of processes.\n";
    labeltext += "Each process may take up to three hours.\n";
    labeltext += "Please carry your daily chores and wait.\n";
    cout << labeltext;
    cout.flush();
    m_label.set_text(labeltext);

    sleep(10); // Back from a three hour function
    newtext = "Back from a three hour function\n";
    labeltext += newtext;
    m_label.set_text(labeltext);
    cout << newtext;
    cout.flush();

    sleep(10); // Back from a three hour function
    newtext = "Back from another three hour function\n";
    labeltext += newtext;
    m_label.set_text(labeltext);
    cout << newtext;
    cout.flush();

    newtext = "Exiting in 1 minute...\n";
    labeltext += newtext;
    m_label.set_text(labeltext);
    cout << newtext;
    cout.flush();
    sleep(60);
    exit(0);
}

int main(int argc, char* argv[])
{
    if (Glib::thread_supported())
        Glib::thread_init();
    else
    {
        cerr << "Threads aren't supported!" << endl;
        exit(1);
    }

    Gtk::Main kit(argc, argv);

    myLabel mylabel;
    Gtk::Main::run(mylabel);
    return 0;
}

Hope the example can help anyone else that wants to output to the gtkmm gui with updates, similar to updating info to the console.

Upvotes: 0

Christian Smith
Christian Smith

Reputation: 615

Like tp1 said in their comment on your question, a timer is going to be the easiest way to do this.

To set a 1.5 second timeout that will call another function, do this (gtkmm 3):

#include <gtkmm.h>
#include <iostream>

using namespace std;

class MyApp : public Gtk::Window{
 public:
    Gtk::Label label;
    bool on_timeout(); //return true to keep the timeout and false to end it
    MyApp();
    virtual ~MyApp();
};

MyApp::MyApp(){
 string mylabeltext = "This is the first line of text in my gui window.\n";

 set_default_size(600, 360);
 set_title("Gtkmm Programming - C++");
 set_position(Gtk::WIN_POS_CENTER);

 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;

 //create slot for timeout signal
 int timeout_value = 1500; //in ms (1.5 sec)
 sigc::slot<bool>my_slot = sigc::mem_fun(*this, &MyApp::on_timeout);
 //connect slot to signal
 Glib::signal_timeout().connect(my_slot, timeout_value);
 show_all_children();
}

MyApp::~MyApp(){

}

bool MyApp::on_timeout(){
 cout << "Continuing after various functions and processing..." << endl;
 string temp = label.get_text();
 temp += "Showing the results of the functions and processing.\n";
 label.set_text(temp);
 return true;
}

int main(int argc, char* argv[])
{
 Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "com.kaze.test");

 MyApp myapp;

 // The Gui Window is displayed
 return app->run(myapp);
}

More info here: https://developer.gnome.org/gtkmm-tutorial/3.3/sec-timeouts.html.en

Upvotes: 1

Related Questions