Hello,
I am new to GTK, in fact it's my first GTK app. Briefly, I have two child threads that generate data, these data are shown in two non-modal dialogs' textviews. I have a couple of problems:
1. I am getting a run-time error on lines 138 and 158: "IA__gtk_text_view_get_buffer: assertion `GTK_IS_TEXT_VIEW (text_view)' failed"
2. The numbers are not automatically scrolled, to see the latest number I have to scroll manually.
3. I can't find to how display parent window and dialogs at a certain position on the screen.
4. Is the app generally alright?
I'd appreciate your input. Thanks in advance!
EDIT: I am using C++ and Ubuntu.
Code:
// g++ -Wall -g -pthread -std=c++0x `pkg-config --cflags --libs gtk+-2.0` gui.cpp -o gui
#include <gtk/gtk.h>
#include <iostream>
using namespace std;
static void destroy (GtkWidget*, gpointer);
static void create_dialog_box1(GtkButton *button, GtkWindow *parent);
static void create_dialog_box2(GtkButton *button, GtkWindow *parent);
pthread_t thread_one, thread_two;
void* thread_one_fun(void* arg);
void* thread_two_fun(void* arg);
GtkWidget* textview1;
GtkTextBuffer *buffer1;
GtkWidget* textview2;
GtkTextBuffer *buffer2;
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
// Create a parent window.
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW (window), "MyGUI");
gtk_container_set_border_width (GTK_CONTAINER (window), 25);
gtk_widget_set_size_request (window, 400, 100);
g_signal_connect(G_OBJECT (window), "destroy", G_CALLBACK(destroy), NULL);
// Create horizontal box.
GtkWidget* hbox = gtk_hbox_new (TRUE, 5);
// Create a new button1 with label
GtkWidget* button1 = gtk_button_new_with_mnemonic("Button One");
gtk_box_pack_start_defaults(GTK_BOX(hbox), button1);
g_signal_connect(G_OBJECT (button1), "clicked", G_CALLBACK (create_dialog_box1), (gpointer) window);
// Create a new button2 with label
GtkWidget* button2 = gtk_button_new_with_label("Button Two");
gtk_box_pack_start_defaults (GTK_BOX (hbox), button2);
g_signal_connect(G_OBJECT (button2), "clicked", G_CALLBACK (create_dialog_box2), (gpointer) window);
// Add buttons to the container.
gtk_container_add (GTK_CONTAINER (window), hbox);
gtk_widget_show_all(window);
// Start data threads.
if ( pthread_create(&thread_one, NULL, thread_one_fun, NULL) != 0 )
cerr << ("Run() error creating thread 1.") << endl << flush;
if ( pthread_create(&thread_two, NULL, thread_two_fun, NULL) != 0 )
cerr << ("Run() error creating thread 2.") << endl << flush;
gtk_main ();
return 0;
}
/* Stop the GTK+ main loop function. */
static void destroy(GtkWidget *window, gpointer data)
{
g_print("KK destroy(): distroy window was pressed.\n");
gtk_main_quit ();
}
static void create_dialog_box1(GtkButton *button, GtkWindow *parent)
{
/* Create a non-modal dialog with one OK button. */
GtkWidget *dialog = gtk_dialog_new_with_buttons("Information 1", parent, GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
// Create textview.
textview1 = gtk_text_view_new();
gtk_widget_set_size_request (textview1, 400, 100);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview1), GTK_WRAP_WORD);
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview1), FALSE);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview1), FALSE);
buffer1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview1));
gtk_text_buffer_set_text(buffer1, "Default value one.\n", -1);
// end of textviews
// Create scrolled window.
GtkWidget* scrolled_win = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
// Add widgets to containter.
gtk_container_add(GTK_CONTAINER (scrolled_win), textview1);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), scrolled_win);
gtk_widget_show_all(dialog);
/* Call gtk_widget_destroy() when the dialog emits the response signal. */
g_signal_connect(G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL);
}
static void create_dialog_box2(GtkButton *button, GtkWindow *parent)
{
/* Create a non-modal dialog with one OK button. */
GtkWidget *dialog = gtk_dialog_new_with_buttons("Information 2", parent, GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
// Create textview
textview2 = gtk_text_view_new();
gtk_widget_set_size_request (textview2, 400, 100);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview2), GTK_WRAP_WORD);
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview2), FALSE);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview2), FALSE);
buffer2 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview2));
gtk_text_buffer_set_text(buffer2, "Default value two.\n", -1);
// end of textviews
// Create scrolled window.
GtkWidget* scrolled_win = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
// Add widgets to containter.
gtk_container_add(GTK_CONTAINER (scrolled_win), textview2);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), scrolled_win);
gtk_widget_show_all(dialog);
/* Call gtk_widget_destroy() when the dialog emits the response signal. */
g_signal_connect(G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL);
}
void* thread_one_fun(void* arg)
{
string str;
for(int i=0;; i++)
{
str = "thread one: " + to_string(i) + "\n";
cout << str << endl << flush;
buffer1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview1)); // I GET RUN TIME ERROR HERE
GtkTextIter iter;
GtkTextMark* mark = gtk_text_buffer_get_insert(buffer1);
gtk_text_buffer_get_iter_at_mark(buffer1, &iter, mark);
gtk_text_buffer_insert(buffer1, &iter, str.c_str(), -1);
sleep(1);
}
return ((void *) 0);
}
void* thread_two_fun(void* arg)
{
string str;
for(int i=0;; i++)
{
str = "thread two: " + to_string(i) + "\n";
cout << str << endl << flush;
buffer2 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview2)); // I GET RUN TIME ERROR HERE
GtkTextIter iter;
GtkTextMark* mark = gtk_text_buffer_get_insert(buffer2);
gtk_text_buffer_get_iter_at_mark(buffer2, &iter, mark);
gtk_text_buffer_insert(buffer2, &iter, str.c_str(), -1);
sleep(1);
}
return ((void *) 0);
}