pointer problem: invoking the method of a pointer?

M

Markus Pitha

Hello,

I have a method which creates a lot of buttons in a GUI window.
My target is it to change the button's label from "0" to "1" from the
just clicked button. (There is a set_label method for Gtk::Button).
My problem is that I don't know how to access the method of a
Gtk::Button through a method written by myself.
Here is the example:

//This method creates the button window (for my problem here not needed)
void GUIMenu::eek:nInputClick() {
Gtk::Table table;
Gtk::HBox hbox;
createTable(table);
matrixWindow.set_title("Adjazenzmatrix");
hbox.pack_start(table);
matrixWindow.add(hbox);
matrixWindow.set_resizable(false);
matrixWindow.show_all();
Gtk::Main::run(matrixWindow);
}

//This method is invoked when a button is clicked. How can I access the
button from the bottom method with this method to change the label of
the button?
void GUIMenu::eek:nMatrixClick(int j, int i, Gtk::Button &button) {
button.set_label(" 1 ");
}

//private
void GUIMenu::createTable(Gtk::Table &tab) {

int knotenAnzahl = spinbutton.get_value_as_int();
for(int i = 0; i < knotenAnzahl; i++) {
for(int j = 0; j < knotenAnzahl; j++) {
Gtk::Button* pButton = Gtk::manage(new Gtk::Button(" 0 "));
if (i == j)
pButton->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("red"));
tab.attach(*pButton, j, j+1, i, i+1);

pButton->signal_clicked().connect(sigc::bind<int, int>
(sigc::mem_fun(*this, &GUIMenu::eek:nMatrixClick), j,
i, pButton));
}
}
}



Thanks,
Markus
 
V

Victor Bazarov

Markus said:
I have a method which creates a lot of buttons in a GUI window.
My target is it to change the button's label from "0" to "1" from the
just clicked button. (There is a set_label method for Gtk::Button).
My problem is that I don't know how to access the method of a
Gtk::Button through a method written by myself.

Have you tried just doing

pButton->set_label(" 1 ");

?
Here is the example:
[..]

Perhaps you're asking how to use specific Gtk functionality (signals?).
Then this is a wrong newsgroup for that. We talk C++ language, not Gtk.

V
 
M

Markus Pitha

Victor said:
Have you tried just doing

pButton->set_label(" 1 ");

No, not in the createTable method. I need to access this button in the
onMatrixClick method.

Perhaps you're asking how to use specific Gtk functionality (signals?).
Then this is a wrong newsgroup for that. We talk C++ language, not Gtk.


No, it's a c++ question about pointer handling, not a question about
signals.



Markus
 
V

Victor Bazarov

Markus said:
No, not in the createTable method. I need to access this button in the
onMatrixClick method.

Uh... But you already do that, don't you? Don't you have the code

button.set_label(" 1 ");

in 'onMatrixClick'. Isn't that "accessing this button"? Doesn't it
do what you need it to do?
No, it's a c++ question about pointer handling, not a question about
signals.

There is no pointer except the 'this' in the 'onMatrixClick' function.

V
 
M

Markus Pitha

Victor said:
Uh... But you already do that, don't you? Don't you have the code

button.set_label(" 1 ");

in 'onMatrixClick'. Isn't that "accessing this button"? Doesn't it
do what you need it to do?

Unfortunately not.
I get error messages like this:

/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h: In member
function »typ ename
sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1, T_arg2,
T_arg 3, void, void, void, void>::type
sigc::adaptor_functor<T_functor>::eek:perator()(T_ arg1, T_arg2,
T_arg3) const [with T_arg1 = int&, T_arg2 = int&, T_arg3 = Gtk::Bu
tton*&, T_functor = sigc::bound_mem_functor3<void, GUIMenu, int, int,
Gtk::Butto n&>]«:
/usr/include/sigc++-2.0/sigc++/adaptors/bind.h:1511: instantiated from
»typena me sigc::adapts<T_functor>::adaptor_type::result_type
sigc::bind_functor<-0x0000 00001, T_functor, T_type1, T_type2,
T_type3, sigc::nil, sigc::nil, sigc::nil, si
gc::nil>::eek:perator()() [with T_functor = sigc::bound_mem_functor3<void,
GUIMenu, int, int, Gtk::Button&>, T_type1 = int, T_type2 = int,
T_type3 = Gtk::Button*]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:103: instantiated from
»static T_return sigc::internal::slot_call0<T_functor,
T_return>::call_it(sigc::internal ::slot_rep*) [with T_functor =
sigc::bind_functor<-0x000000001, sigc::bound_mem_ functor3<void,
GUIMenu, int, int, Gtk::Button&>, int, int, Gtk::Button*, sigc::n
il, sigc::nil, sigc::nil, sigc::nil>, T_return = void]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:110: instantiated from
»static void* (* sigc::internal::slot_call0<T_functor,
T_return>::address())(void*) [wit h T_functor =
sigc::bind_functor<-0x000000001, sigc::bound_mem_functor3<void, GU
IMenu, int, int, Gtk::Button&>, int, int, Gtk::Button*, sigc::nil,
sigc::nil, si gc::nil, sigc::nil>, T_return = void]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:454: instantiated from
»sigc::s lot0<T_return>::slot0(const T_functor&) [with T_functor
= sigc::bind_functor<-0x 000000001,
sigc::bound_mem_functor3<void, GUIMenu, int, int, Gtk::Button&>, int,
int, Gtk::Button*, sigc::nil, sigc::nil, sigc::nil, sigc::nil>,
T_return = void ]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:1130: instantiated from
»sigc:: slot<T_return, sigc::nil, sigc::nil, sigc::nil,
sigc::nil, sigc::nil, sigc::nil, sigc::nil>::slot(const
T_functor&) [with T_functor = sigc::bind_functor<-0x0000 00001,
sigc::bound_mem_functor3<void, GUIMenu, int, int, Gtk::Button&>, int,
int , Gtk::Button*, sigc::nil, sigc::nil, sigc::nil, sigc::nil>,
T_return = void]«
GUIMenu.cpp:88: instantiated from here
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:123: Fehler:
keine Übere instimmung für Aufruf von
»(sigc::bound_mem_functor3<void, GUIMenu, int, int, Gt
k::Button&>) (int&, int&, Gtk::Button*&)«
/usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:1984: Anmerkung:
Kandidaten si nd: T_return sigc::bound_mem_functor3<T_return,
T_obj, T_arg1, T_arg2, T_arg3>:: operator()(typename
sigc::type_trait<T_arg3>::take, typename sigc::type_trait<T_
arg4>::take, typename sigc::type_trait<T_arg5>::take) const [with
T_return = voi d, T_obj = GUIMenu, T_arg1 = int, T_arg2 = int,
T_arg3 = Gtk::Button&]
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:123: Fehler:
Return-Anwe isung mit Wert in »void« zurückgebender Funktion
 
V

Victor Bazarov

Markus said:
Victor said:
Uh... But you already do that, don't you? Don't you have the code

button.set_label(" 1 ");

in 'onMatrixClick'. Isn't that "accessing this button"? Doesn't it
do what you need it to do?

Unfortunately not.
I get error messages like this:

/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h: In member
function »typ ename
sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1, T_arg2,
T_arg 3, void, void, void, void>::type
sigc::adaptor_functor<T_functor>::eek:perator()(T_ arg1, T_arg2,
T_arg3) const [with T_arg1 = int&, T_arg2 = int&, T_arg3 = Gtk::Bu
tton*&, T_functor = sigc::bound_mem_functor3<void, GUIMenu, int,
int, Gtk::Butto n&>]«:
/usr/include/sigc++-2.0/sigc++/adaptors/bind.h:1511: instantiated
from »[..]
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:123: Fehler:
Return-Anwe isung mit Wert in »void« zurückgebender Funktion

Sorry, I don't read or speak German that well.

Read http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8
*carefully*. Keep in mind that Gtk is not part of C++. Whatever
'sigc' is, it's not known _here_.

V
 
T

Thomas J. Gritzan

Markus said:
I have a method which creates a lot of buttons in a GUI window.
My target is it to change the button's label from "0" to "1" from the
just clicked button. (There is a set_label method for Gtk::Button).
My problem is that I don't know how to access the method of a
Gtk::Button through a method written by myself.
Here is the example: [...]
//This method is invoked when a button is clicked. How can I access the
button from the bottom method with this method to change the label of
the button?
void GUIMenu::eek:nMatrixClick(int j, int i, Gtk::Button &button) {
button.set_label(" 1 ");
}

Compare:
Gtk::Button &button

[...]
Gtk::Button* pButton = Gtk::manage(new Gtk::Button(" 0 "));

with:
Gtk::Button* pButton

[...]
pButton->signal_clicked().connect(sigc::bind<int, int>
(sigc::mem_fun(*this, &GUIMenu::eek:nMatrixClick), j,
i, pButton));

Do you actually know the difference between a _pointer_ and a _reference_?
 
M

Markus Pitha

Hello,
Compare:
Gtk::Button &button

[...]
Gtk::Button* pButton = Gtk::manage(new Gtk::Button(" 0 "));

with:
Gtk::Button* pButton

Do you actually know the difference between a _pointer_ and a _reference_?

I'll get the address in the first case and I have a pointer in the
second one. I have difficulties to understand how to invoke the method
"set_label" of of an object (Gtk::Button) while pButton is a pointer on
Gtk::Button, whereby pButton only exists in the method createTable.
So my though was to get access to this method through the address of the
pointer pButton as I did do it with "table" in the first method.
pButton is the address of "new Button", as you saw in this line:

Gtk::Button *pButton = Gtk::manage(new Gtk::Button(" 0 "));

When I give over the pointer as parameter in onMatrixClick, I thought
abount giving the address and I should be able to change the value of
"new Button", but you saw the error messages while compiling.
I already tried different approaches without "&" or ** but I only get
error messages. What do I wrong?

Markus
 
V

Victor Bazarov

Markus said:
Hello,
Compare:
Gtk::Button &button

[...]
Gtk::Button* pButton = Gtk::manage(new
Gtk::Button(" 0 "));

with:
Gtk::Button* pButton

Do you actually know the difference between a _pointer_ and a
_reference_?

I'll get the address in the first case and I have a pointer in the
second one. I have difficulties to understand how to invoke the method
"set_label" of of an object (Gtk::Button) while pButton is a pointer
on Gtk::Button, whereby pButton only exists in the method createTable.
So my though was to get access to this method through the address of
the pointer pButton as I did do it with "table" in the first method.
pButton is the address of "new Button", as you saw in this line:

Gtk::Button *pButton = Gtk::manage(new Gtk::Button(" 0 "));

When I give over the pointer as parameter in onMatrixClick, I thought
abount giving the address and I should be able to change the value of
"new Button", but you saw the error messages while compiling.
I already tried different approaches without "&" or ** but I only get
error messages. What do I wrong?

Just a shot in the dark: try using *pButton at the end of the 'connect'
call.

V
 
M

Markus Pitha

Victor said:
Just a shot in the dark: try using *pButton at the end of the 'connect'
call.

Unfortunately that doesn't work either. I get the same compiling errors.
At the moment I have no more ideas too.


Markus
 
M

Markus Pitha

I finally found the solution:

void GUIMenu::eek:nMatrixClick(int j, int i, Gtk::Button *button) {
button->set_label(" 1 ");
}

//private
void GUIMenu::createTable(Gtk::Table &tab) {

int knotenAnzahl = spinbutton.get_value_as_int();
for(int i = 0; i < knotenAnzahl; i++) {
for(int j = 0; j < knotenAnzahl; j++) {
Gtk::Button *pButton = Gtk::manage(new Gtk::Button(" 0 "));
if (i == j)
pButton->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("red"));
tab.attach(*pButton, j, j+1, i, i+1);

pButton->signal_clicked().connect(sigc::bind<int, int>
(sigc::mem_fun(*this, &GUIMenu::eek:nMatrixClick), j,
i, pButton));
}
}
}


Actually I don't understand why this works due to the following thought:

pButton is a pointer. In onMatrixClick I declare a pointer. When I pass
pButton to onMatrixClick, I thought it's just a copy of the pointer
because I don't handle with addresses (&). So why does it work to change
the label in this way?

Markus
 
V

Victor Bazarov

Markus said:
I finally found the solution:

void GUIMenu::eek:nMatrixClick(int j, int i, Gtk::Button *button) {
button->set_label(" 1 ");
}

//private
void GUIMenu::createTable(Gtk::Table &tab) {

int knotenAnzahl = spinbutton.get_value_as_int();
for(int i = 0; i < knotenAnzahl; i++) {
for(int j = 0; j < knotenAnzahl; j++) {
Gtk::Button *pButton = Gtk::manage(new Gtk::Button(" 0 "));
if (i == j)
pButton->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("red"));
tab.attach(*pButton, j, j+1, i, i+1);

pButton->signal_clicked().connect(sigc::bind<int, int>
(sigc::mem_fun(*this, &GUIMenu::eek:nMatrixClick), j,
i, pButton));
}
}
}


Actually I don't understand why this works due to the following
thought:
pButton is a pointer. In onMatrixClick I declare a pointer. When I
pass pButton to onMatrixClick,

I am afraid you _don't_ actually pass anything to anything. The
'bind' and 'connect' *probably* don't call the function, they just
establish the callback.
I thought it's just a copy of the
pointer because I don't handle with addresses (&). So why does it
work to change the label in this way?

What *label*?

V
 
M

Markus Pitha

Victor said:
I am afraid you _don't_ actually pass anything to anything. The
'bind' and 'connect' *probably* don't call the function, they just
establish the callback.

However. I'm interested in the backgrounds concerning the access from
"onMatrixClick" to "new Button" in "createTable". I'm still not sure why
it works and what exactly is going on here.
What *label*?

The label of the button. (first "0", then "1").

Markus
 
V

Victor Bazarov

Markus said:
However. I'm interested in the backgrounds concerning the access from
"onMatrixClick" to "new Button" in "createTable". I'm still not sure
why it works and what exactly is going on here.

Put a breakpoint there, run it until it's stopped there, examine the
call stack. Get a book on Gtk and see how the signals work (there has
to be some explanation there, right?)
The label of the button. (first "0", then "1").

Ah... That's not a C++ question. It's a Gtk question.

V
 
M

Markus Pitha

Victor said:
Put a breakpoint there, run it until it's stopped there, examine the
call stack. Get a book on Gtk and see how the signals work (there has
to be some explanation there, right?)

I have only some sophisticated text editor, not a whole c++ development
environment, because I mostly work with java on eclipse.

Ah... That's not a C++ question. It's a Gtk question.

What difference is it for you if I use a method of an object "Foo", an
object "FooFoo", or an object "Gtk::Button"?
I didn't talk about especially Gtk but about an object which is accessed
with any method.


M.
 
V

Victor Bazarov

Markus said:
I have only some sophisticated text editor, not a whole c++
development environment, because I mostly work with java on eclipse.



What difference is it for you if I use a method of an object "Foo", an
object "FooFoo", or an object "Gtk::Button"?
I didn't talk about especially Gtk but about an object which is
accessed with any method.

You asked why it was important to define some 'menuClicked' or some
such member function so that its third argument would be *a pointer*
to a Button class, and not a reference. Apparently, it is important
to use a pointer so that the function could be made into *what seems
to be* a callback for Gtk messaging system. Why doesn't a reference
work? Most likely because Gtk was designed that way. Who here can
tell? It's off-topic.

Calling a member function of a class through a pointer to object
requires the -> operator, calling it through a reference to object
requires the . operator, that's the C++ requirement. It has nothing
to do with your problem, however.

struct Button {
void setLabel(const char*) { /* nothing */ }
};

void foo(int i, int j, Button* pButton) {
pButton->setLabel(" 1 "); // here we use a pointer
}

void foo(int i, int j, Button& rButton) {
rButton.setLabel(" 1 "); // here we use a reference
}

int main() {
Button button;

foo(0, 0, &button); // call the one that takes a pointer
foo(1, 1, button); // call the one that takes a reference
}

V
 
I

I V

void GUIMenu::eek:nMatrixClick(int j, int i, Gtk::Button &button) {
button.set_label(" 1 ");
}

This function takes a Gtk::Button& .
//private
void GUIMenu::createTable(Gtk::Table &tab) {

int knotenAnzahl = spinbutton.get_value_as_int();
for(int i = 0; i < knotenAnzahl; i++) {
for(int j = 0; j < knotenAnzahl; j++) {
Gtk::Button* pButton = Gtk::manage(new Gtk::Button(" 0 "));
if (i == j)
pButton->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("red"));
tab.attach(*pButton, j, j+1, i, i+1);

pButton->signal_clicked().connect(sigc::bind<int, int>
(sigc::mem_fun(*this, &GUIMenu::eek:nMatrixClick), j,
i, pButton));

And here, you are passing a pointer to the above function, and a
Gtk::Button* ; I would guess that this leads to something trying to
treat GUIMenu::eek:nMatrixClick as if it took a Gtk::Button* .

Try either changing GUIMenu::eek:nMatrixClick to take a Gtk::Button*, or
dereferencing pButton in the call to signal_clicked.
 
I

I V

Actually I don't understand why this works due to the following thought:

pButton is a pointer. In onMatrixClick I declare a pointer. When I pass
pButton to onMatrixClick, I thought it's just a copy of the pointer
because I don't handle with addresses (&). So why does it work to change
the label in this way?

It passes a copy of the _pointer_. But the copied pointer and the original
pointer point to the same _object_. So, there's only one object. If you
modify the object via the pointer in onMatrixClick, and then you access the
object via the pointer in createTable, you're accessing the same object;
any modification made via one pointer will be visible via the other
pointer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top