2013-07-30 78 views
0

有人可以幫助解決如何在沒有用戶輸入的情況下更新gui窗口的困惑。如何在C++代碼創建後更新gtkmm gui屏幕

換句話說,我希望能夠輸出文本到任一個或兩個控制檯我們的gui窗口。

目前我可以調用GUI窗口(例如帶有標籤的窗口)並輸出初始文本。但是,該過程在窗口關閉之前不會返回到我的C++代碼。我試圖弄清楚如何(或在哪裏有我的代碼)在GUI窗口退出之前更新GUI屏幕。

這是一個例子:

#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; 
} 

文本的最後一行,直到GUI退出從未打印到控制檯。 mylabeltext的最後一行從不打印到標籤窗口。

我想要描述的是如何在我的C++代碼中運行其他例程並將輸出更新爲控制檯和gui窗口而不關閉GUI窗口以繼續C++例程的同時保持gtkmm窗口處於活動狀態。

我可以找到的所有示例都使用代碼中的按鈕。我已經測試和足夠的實驗了,我可以在按下按鈕後更新GUI屏幕。但是,我不想依靠用戶進行屏幕更新。我希望能夠運行光盤掃描和其他功能,並定期更新屏幕,以便用戶可以看到進度並知道該程序仍在工作而不是死機。

一些,我已經在我的嘗試是瞭解該研究的資源包括:

+0

使用定時器或閒置。 – tp1

+0

我不明白你對計時器的意思。但是,如果我在運行sleep()函數之後嘗試附加新文本,則每個sleep()函數之後都不會出現窗口。如果我在窗口顯示後添加sleep()函數,窗口將保持顯示,並且sleep()函數將永遠不會執行,直到gui窗口退出。 –

回答

0

像TP1他們對您的問題評論說: ,計時器將是最簡單的方法來做到這一點。

要設置一個1.5秒的超時,將調用另一個函數,這樣做(的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); 
} 

此處瞭解詳情:https://developer.gnome.org/gtkmm-tutorial/3.3/sec-timeouts.html.en

+0

謝謝,Senshikaze。這是一個開始。我相信有一些東西缺失(很可能以我幼稚的方式描述目標)。 這將放置一個無限循環,其中「繼續執行各種功能...」「可能是因爲我不懂如何使用」myapp「類,我將它放在主(Gtk :: Main :: run(myapp);)中,替換run(window )with run(myapp) 這是我的目標,是通過代碼到最後一行,在屏幕上留下最後一行輸出,等待用戶讀完後退出gui。 –

+0

具體做什麼你想在timeout函數中返回false(on_timeout)。MyApp類是一個我構建的繼承Gtk :: Window類的類。 – senshikaze

+0

我用return false替換了return true。它似乎工作。但是,(I我確定這是一個我更瞭解代碼的問題,我正在研究這個代碼,但是我仍然處於一個不同的地方,我增加了30秒的睡眠時間(以表示其他活動將會產生新的輸出,然後添加行:temp + =「一個結果nother函數「。並試圖用label.set_text(temp)將它添加到屏幕上。 gui窗口在30秒內褪色,然後立即打印。我試圖根據每個步驟的輸出在屏幕上保留所有文本。 –

0

這是粗糙,但這個功能對我試圖做:

#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; 
} 

希望的例子可以幫助其他人想要輸出與更新,類似於更新信息到控制檯gtkmm的GUI。