PDA

View Full Version : attempting to connect button to aboutQt()



ajax
2nd December 2010, 22:14
Hi All,

I am attempting to set up a signal/slot arrangement for a button.

I read a recommendation somewhere that a way to debug the signal part of a connection statement was to do something like:


connect(myObj, SIGNAL(mySignal()), qApp, SLOT(aboutQt()));

I thought I knew a good idea when I saw one. Anyway, I encounter a problem with this trifling task.



class ButtonDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit ButtonDelegate(QObject *parent=0);
~ButtonDelegate();

// code redacted for bevity

private:
QPushButton *button;

};

ButtonDelegate::ButtonDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
std::cout << "in ButtonDelegate() ctor: \n" << endl;
connect(button, SIGNAL(clicked()), qApp, SLOT(aboutQt()));
std::cout << "after ButtonDelegate() ctor is complete \n" << endl;

}


This code crashes at the connect statement. "in ButtonDelegate()..." is printed to the console and "after ButtonDelegate().." is not printed.

Does anyone have an idea what I am getting wrong?

Timoteo
2nd December 2010, 22:18
ajax, what are we going to do with you?:D Did you initialize button?

ajax
2nd December 2010, 23:03
No the button is not initialized at this time. I thought that just the name of the pointer was sufficient for the connect() function. I gather from your question that I didn't have that right.

this button is instantiated during the lifetime of the application if and only if the user hovers his mouse over a row in a treeview. Here is the code:


QWidget * ButtonDelegate::createEditor( QWidget * parent,
const QStyleOptionViewItem & option,
const QModelIndex & index ) const
{
// if the current column is the 'share' button's column
if ( index.column() == buttonColumn )
{ // create the button that will be located in this view item
return new QPushButton("Share", parent);
}
else
{
return QStyledItemDelegate::createEditor(parent, option, index );
}
}


Now, as I understand it, createEditor() is invoked when openPersistentEditor() is invoked. Another detail, the spec calls for a 'hidden' button to be located in every cell in column zero of a spreadsheet-like view. I handle all of this in a mouseMoveEvent():


void MyTreeView::mouseMoveEvent(QMouseEvent *event)
{
QAbstractItemModel *m(model());

// Only do something when a model is set.
if (m)
{
QModelIndex index = this->indexAt(event->pos());
if (index.isValid())
{

// if the mouse has moved to another row
if (index.row() != m_currentRow)
{
m_currentRow = index.row();

// clear buttons from all rows
for ( int i = 0; i < m->rowCount(); ++i )
{
this->closePersistentEditor( m->index(i, 0, QModelIndex()) );
}

// create button on mouse's current row
this->openPersistentEditor(m->index(m_currentRow, 0, QModelIndex() ));


}
}
else // model is invalid
{
m_currentRow = -1;
}
}

QTreeView::mouseMoveEvent(event);
}


One other detail: The buttonDelegate class has a button pointer:


class ButtonDelegate : public QStyledItemDelegate
{
Q_OBJECT

public:
explicit ButtonDelegate(QObject *parent=0);
~ButtonDelegate();

// code redacted for bevity
private:

QPushButton *button;

};

I'm faintly embarrassed to admit that I didn't notice the button pointer has evidently fallen out of use. This code had been through a number of major changes before wysota guided me to a solution that seemed to work. But that solution is rather different than my initial approach. It seems that the framework holds the pointer to the button for the duration of the editor's life.

But, on the other hand, if I comment-out the references to the 'button pointer' the app crashes, and I don't know why.

OK, Timoteo, based on your comment it appears that I need to create the connection that uses the button click as a signal in mouseMoveEvent(), just after the return from openPersistentEditor(). If so, does this mean that disconnect() should be called after closePersistentEditor() is called? I guess it would.

wysota
2nd December 2010, 23:15
I thought that just the name of the pointer was sufficient for the connect() function.
In C++ there is no such thing as "name of the pointer".


This code had been through a number of major changes before wysota guided me to a solution that seemed to work.
Please don't mention my name in posts that involve this "solution" you are using. This is a really bad approach and I didn't guide you to it. And even if I unintentionally did then I won't admit it.

Timoteo
2nd December 2010, 23:27
I think you've already lost a handle on your ownership semantics (you do have them, right?). Take a few moments to go and do something else, maybe a spot of tea, and consider who should be owning what. Right now, it appears that you don't have a strategy in place.

I also sense a fundamental lack of understanding of what a pointer truly is. Perhaps that is what you should think on first.

ajax
3rd December 2010, 00:01
OK, guys, I do know what a pointer is. I have been programming in C for a lot of years and in C++, on and off, for several years. Since you want it in jargon, what I should have said something along the lines of "passed the pointer to the button in first argument to the call to the connect() function." And, of course, since the variables, including pointers, are uniquely identified by their names (pace, all quibbling about namespaces, scope, names in outer scopes being hidden by identical names in inter-scopes, etc., etc.) I just naively assumed that a phrase like "name of the pointer" could be used without bringing the language lawyers down on me. My bad.

Regarding lack of strategy: you have a point. My problem is that this is my first Qt application and I am still working out how things are done in the Qt world. Since I am just beginning this process of discovery I am relatively clueless, but I believe that experience will cure that. Already a few of my initial approaches have exploded on contact with the way Qt actually does things. Of course I would rather have guessed correctly in the first place, but the necessary precondition of guessing correctly is to have the subject matter expertise that newbies have not yet obtained.

wysota
3rd December 2010, 00:07
OK, guys, I do know what a pointer is. I have been programming in C for a lot of years and in C++, on and off, for several years. Since you want it in jargon, what I should have said something along the lines of "passed the pointer to the button in first argument to the call to the connect() function." And, of course, since the variables, including pointers, are uniquely identified by their names (pace, all quibbling about namespaces, scope, names in outer scopes being hidden by identical names in inter-scopes, etc., etc.) I just naively assumed that a phrase like "name of the pointer" could be used without bringing the language lawyers down on me. My bad.
To be honest you didn't convince me. From what I understood you thought that if you pass a pointer variable named "x" to the connect statement and then you would assign some object to "x" then when Qt dereferences the "x" pointer it will be pointing to the object that you "in the meantime" assigned to "x" which leads straight to a conclusion that your understanding of pointers and function calls is not as perfect as you may have thought.


Regarding lack of strategy: you have a point. My problem is that this is my first Qt application and I am still working out how things are done in the Qt world. Since I am just beginning this process of discovery I am relatively clueless, but I believe that experience will cure that. Already a few of my initial approaches have exploded on contact with the way Qt actually does things. Of course I would rather have guessed correctly in the first place, but the necessary precondition of guessing correctly is to have the subject matter expertise that newbies have not yet obtained.
Let me make your decisions easier - if you create an editor for a model index, the view takes responsibility of it and there is no way you can change that. The object may get deleted behind your back at an arbitrary point in time.