GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED] gtkmm Gtk::Builder question regarding ComboBoxes

 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming
Author Message
roguetech



Joined: 20 Dec 2008
Posts: 4

PostPosted: Sat Dec 20, 2008 7:49 pm    Post subject: [SOLVED] gtkmm Gtk::Builder question regarding ComboBoxes Reply with quote

Hi Everyone!
I am somewhat new to programming in gui's and have some moderate skill in C and C++. I am trying to learn gui's so I can interface with systems that I make (either serial, network etc..) I decided to run everything on gtkmm as it seems to be a lot easier to read and reference (I find gtk+ w/ C a little hard on the eye to read.) I am going through the motions of creating guis using builder as I would rather depend on less dependancies (glademm/libglademm) So far I have come across using entry boxes and buttons and can manipulate them to a degree. Right now when you run the program, it generates what you see below and workd that when you type something into input it goes to output and fills input back with <Insert Text>

Input:<Insert Text>
Output:__________
[Combo]^] [Apply]

But I would like to interface with combo boxes that glade3 creates ( use gtk-builder-convert to generate .xml files for builder) my combobox contains 4 entries Hello, World, Good, Bye. Ideally I would like the program to work as above but instead, fill Input with what the combos contents are... any help would be greatly appreciated. In the next post I will include the following code and xml file.


Last edited by roguetech on Mon Dec 22, 2008 11:28 pm; edited 1 time in total
Back to top
roguetech



Joined: 20 Dec 2008
Posts: 4

PostPosted: Sat Dec 20, 2008 7:50 pm    Post subject: Reply with quote

I get this error when trying to run the program:
Code: (Plaintext)
1
 (foobar:30683): CRITICAL **: Gtk::Builder::get_widget(): dynamic_cast<> failed.


Also the program crashes... I am very clueless as to what to do...

Here is the corresponding code and xml file

Code foobar.cpp
Code: (C++)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <gtkmm-2.4/gtkmm.h>
#include <iostream>
#include <string>

Gtk::Window* pWindow = 0;
Gtk::Entry* pInEntry = 0;
Gtk::Entry* pOutEntry = 0;
Gtk::ComboBoxText* pCombo = 0;

void on_ApplyButton_clicked()
{
    std::string sText;
    Glib::ustring text = pCombo->get_active_text();
    sText = pInEntry->get_text();
    pOutEntry->set_text(sText);
    pInEntry->set_text(text);

}

void on_ComboBox_changed()
{
     Glib::ustring text = pCombo->get_active_text();
      if(!(text.empty()))
        std::cout << "Combo changed: " << text << std::endl;

}

int main (int argc, char **argv)
{
  Gtk::Main kit(argc, argv);

  Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();
  try
 
{
    refBuilder->add_from_file("foobar.xml");
  }
  catch(const Gtk::BuilderError& ex)
  {
    std::cerr << ex.what() << std::endl;
    return 1;
  }

  refBuilder->get_widget("FoobarWindow", pWindow);
  refBuilder->get_widget("InEntry", pInEntry);
  refBuilder->get_widget("OutEntry", pOutEntry);
  refBuilder->get_widget("ComboBox", pCombo);

  pInEntry->set_text("<Insert Text>");
  if(pWindow)
  {


    Gtk::Button* pButton = 0;
    refBuilder->get_widget("ApplyButton", pButton);

    if(pButton)
    {
      pButton->signal_clicked().connect( sigc::ptr_fun(on_ApplyButton_clicked) );
    }

    kit.run(*pWindow);
  }

  return 0;
}


Xml foobar.xml
Code: (XML/HTML)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?xml version="1.0"?>
<!--Generated with glade3 3.4.5 on Sat Dec 20 14:49:51 2008 -->
<interface>
  <object
class="GtkListStore" id="model1">
    <columns>
      <column
type="gchararray"/>
    </columns>
    <data>
      <row>
        <col
id="0">Hello</col>
      </row>
      <row>
        <col
id="0">World</col>
      </row>
      <row>
        <col
id="0">Good</col>
      </row>
      <row>
        <col
id="0">Bye</col>
      </row>
    </data>
  </object>
  <object
class="GtkWindow" id="FoobarWindow">
    <property
name="border_width">4</property>
    <child>
      <object
class="GtkVBox" id="vbox1">
        <property
name="visible">True</property>
        <child>
          <object
class="GtkHBox" id="hbox1">
            <property
name="visible">True</property>
            <child>
              <object
class="GtkLabel" id="InLabel">
                <property
name="width_request">60</property>
                <property
name="visible">True</property>
                <property
name="label" translatable="yes">Input:</property>
              </object>
              <packing>
                <property
name="expand">False</property>
                <property
name="fill">False</property>
              </packing>
            </child>
            <child>
              <object
class="GtkEntry" id="InEntry">
                <property
name="width_request">200</property>
                <property
name="visible">True</property>
                <property
name="can_focus">True</property>
              </object>
              <packing>
                <property
name="expand">False</property>
                <property
name="fill">False</property>
                <property
name="position">1</property>
              </packing>
            </child>
          </object>
        </child>
        <child>
          <object
class="GtkHBox" id="hbox2">
            <property
name="visible">True</property>
            <child>
              <object
class="GtkLabel" id="OutLabel">
                <property
name="width_request">60</property>
                <property
name="visible">True</property>
                <property
name="label" translatable="yes">Output:</property>
              </object>
              <packing>
                <property
name="expand">False</property>
                <property
name="fill">False</property>
              </packing>
            </child>
            <child>
              <object
class="GtkEntry" id="OutEntry">
                <property
name="width_request">200</property>
                <property
name="visible">True</property>
                <property
name="can_focus">True</property>
              </object>
              <packing>
                <property
name="expand">False</property>
                <property
name="fill">False</property>
                <property
name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property
name="position">1</property>
          </packing>
        </child>
        <child>
          <object
class="GtkHBox" id="hbox3">
            <property
name="visible">True</property>
            <child>
              <object
class="GtkComboBox" id="ComboBox">
                <property
name="visible">True</property>
                <property
name="wrap_width">1</property>
                <property
name="model">model1</property>
                <child>
                  <object
class="GtkCellRendererText" id="renderer1"/>
                  <attributes>
                    <attribute
name="text">0</attribute>
                  </attributes>
                </child>
              </object>
              <packing>
                <property
name="expand">False</property>
              </packing>
            </child>
            <child>
              <object
class="GtkButton" id="ApplyButton">
                <property
name="width_request">100</property>
                <property
name="height_request">30</property>
                <property
name="visible">True</property>
                <property
name="can_focus">True</property>
                <property
name="receives_default">True</property>
                <property
name="label" translatable="yes">gtk-apply</property>
                <property
name="use_stock">True</property>
              </object>
              <packing>
                <property
name="expand">False</property>
                <property
name="fill">False</property>
                <property
name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property
name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
[/code]
Back to top
tadeboro
Never Seen the Sunlight


Joined: 23 Jul 2008
Posts: 375
Location: Slovenia

PostPosted: Sun Dec 21, 2008 2:36 pm    Post subject: Reply with quote

Hello and welcome to the Gtk+ forums.

The main problem in your application is that you are trying to access values from combo box via simplified text interface, but Glade produces only fully fledged tree model interface.

I'm not a C++ programmer and don't use gtkmm, but I can help you with a conceptual description of the process.

First, refBuilder->get_widget("ComboBox", pCombo); will return Gtk::ComboBox and NOT Gtk::ComboBoxtText. This modification should get rid of that error message when running application.

In your on_ApplyButton_cliked() function, you need to use get_active method on your combo box to obtain Gtk::TreeModel::iterator and then extract text from model, pointed to by the iterator.

The approximately the same modifications are needed in your on_ComboBox_changed callback function.

For more info about Gtk::TreeModel see gtkmm book here: http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/chapter-treeview.html#sec-treeview-model (the "Setting values" and "Getting values" parts are especially important).
Back to top
roguetech



Joined: 20 Dec 2008
Posts: 4

PostPosted: Mon Dec 22, 2008 12:57 am    Post subject: Reply with quote

Hey thanks tadeboro!

I will try read that and try it out as soon as I get a chance, I really do appreciate the response! I will read and try to understand the TreeView article, once I can get an example working I will post it back on this thread.
Again thanks!
Back to top
roguetech



Joined: 20 Dec 2008
Posts: 4

PostPosted: Mon Dec 22, 2008 11:27 pm    Post subject: Reply with quote

Hey again!

Well I went to work and one of my supervisors looked at what you said and pointed me in the right direction, it now seems to work fine. Here is the corresponding code.

Code: (C++)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <gtkmm-2.4/gtkmm.h>
#include <iostream>
#include <string>

Gtk::Window* pWindow = 0;
Gtk::Entry* pInEntry = 0;
Gtk::Entry* pOutEntry = 0;
Gtk::ComboBox* pCombo = 0;

void on_ApplyButton_clicked()
{
    std::string sText;
    Glib::ustring text;
    Gtk::TreeModel::iterator iter = pCombo->get_active();
    Gtk::TreeModel::Row row = *iter;

    sText = pInEntry->get_text();

    row.get_value(0, text);
    pOutEntry->set_text(sText+" "+text);

    pInEntry->set_text("<Insert Text>");

}

void on_ComboBox_changed()
{
    Glib::ustring text;

    Gtk::TreeModel::iterator iter = pCombo->get_active();

    Gtk::TreeModel::Row row = *iter;
    row.get_value(0, text);

    std::cout << "ComboBox changed to " << text << std::endl;

}

int main (int argc, char **argv)
{
  Gtk::Main kit(argc, argv);

  Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();
  try
 
{
    refBuilder->add_from_file("foobar.xml");
  }
  catch(const Gtk::BuilderError& ex)
  {
    std::cerr << ex.what() << std::endl;
    return 1;
  }

  refBuilder->get_widget("FoobarWindow", pWindow);
  refBuilder->get_widget("InEntry", pInEntry);
  refBuilder->get_widget("OutEntry", pOutEntry);
  refBuilder->get_widget("ComboBox", pCombo);

  if(pCombo){

      pCombo->signal_changed().connect(sigc::ptr_fun(on_ComboBox_changed));
  }

  pInEntry->set_text("<Insert Text>");
  if(pWindow)
  {


    Gtk::Button* pButton = 0;
    refBuilder->get_widget("ApplyButton", pButton);

    if(pButton)
    {
      pButton->signal_clicked().connect( sigc::ptr_fun(on_ApplyButton_clicked) );
    }

    kit.run(*pWindow);
  }

  return 0;
}


I appreciate the help! Where you pointed me helped out quite a bit! Thanks again!
Back to top
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming All times are GMT
Page 1 of 1

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP