PDA

View Full Version : Connect external widget(slider, linedit) to QTableWidgetItem



fatecasino
1st February 2011, 15:40
I am trying to connect external widgets(slider, combobox, lineedit, etc) to specific QTableWidgetItem.
The widgets are not embed into the QTableWidget.
All the widgets have their own Signals, which is really fantastic,
BUT the QTableWidgetItem have no SLOTS!
How can i set the values of the QTableWidgetItems using other widgets outside the QTableWidget?
I tried something like the code below but it simply does not work



//setting up the table
QTableWidget *dataSheet = new QTableWidget;
dataSheet->setRowCount(3);
dataSheet->setColumnCount(7);

//initializing the QTableWidgetItem
int row = 0, col = 0;
QTableWidgetItem *newItem = new QTableWidgetItem(tr("%1").arg(343.3432));
dataSheet->setItem(row, col, newItem);

//creating external widget
QLineEdit *action = new QLineEdit;

//trying to connect?!
connect(action, SIGNAL( textChanged ( const QString & ) ), newItem, SLOT( setText ( const QString & ) ));

any suggestions?!

high_flyer
1st February 2011, 15:54
BUT the QTableWidgetItem have no SLOTS!
That's because QTableWidgetItem is not a QObject.


How can i set the values of the QTableWidgetItems using other widgets outside the QTableWidget?

You can make a slot in your table widget, connect to that slot, and in it set the data to the items you want.

But it would better if you understand how Model/View (http://doc.trolltech.com/4.7/model-view-programming.html) works, to deal with data correctly through the model.

fatecasino
1st February 2011, 20:58
You can make a slot in your table widget, connect to that slot, and in it set the data to the items you want.
QTableWidget and the other widgets(slider, lineedit, etc) belong to one-central widget MyWidget.
do you mean to overload the QTableWidget class inserting a custom SLOT or to just add a SLOT to MyWidget?

fatecasino
2nd February 2011, 16:56
i created this (doesn't work)



class MyTableItem : public QTableWidgetItem
{
Q_OBJECT

public:

MyTableItem(const QString &);


public Q_SLOTS:
void setAction(const QString &);


};

when I remove the Q_OBJECT I cannot add a public Q_SLOTS
When I add the Q_OBJECT I get several errors like


error: ‘staticMetaObject’ is not a member of ‘QTableWidgetItem’
/usr/include/qt4/QtCore/qobject.h:296: error: ‘QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData> QObject::d_ptr’ is protected

The idea is mainly to overload the QTableWidgetItem in order to add slots.
Am i completely wrong?

high_flyer
2nd February 2011, 17:02
when I remove the Q_OBJECT I cannot add a public Q_SLOTS
When I add the Q_OBJECT I get several errors like
Again, QTableWidgetItem is NOT a QObject.
Only QObject can use the Q_OBJECT macro, and use signals/ slots.

stampede
2nd February 2011, 17:03
As high_flyer said, QTableWidgetItem is not a QObject, if your class inherits only QTreeWidgetItem it wont be a QObject either.
You need to subclass QObject as well:

class MyTableItem : public QObject, public QTableWidgetItem

fatecasino
2nd February 2011, 23:11
thank you very much! It worked indeed:

MyTableItem.h

class MyTableItem : public QObject, public QTableWidgetItem
{

Q_OBJECT

public:

MyTableItem(const QString &);


public slots:
void setTextSlot(const QString &);


};

myTableItem.cpp

#include <myTableItem.h>

MyTableItem ::MyTableItem (const QString & text)
: QTableWidgetItem(text)
{
setText(text);
}



void MyTableItem ::setTextSlot(const QString & t)
{
setText(t);

}

in the main

MyTable *dataSheet = new MyTable;//i have overloaded the QTableWidget too
MyTableItem *test = new MyTableItem("test");
dataSheet->setItem(2, 2, test);
QLineEdit *action = new QLineEdit;
connect(action, SIGNAL( textChanged ( const QString & ) ), test, SLOT( setTextSlot ( const QString & ) ));

fatecasino
3rd February 2011, 01:20
Now, I have a slightly different problem...
I want the action QLineEdit to set the values of a specific cell of the MyTable dataSheet (it's an overloaded QTableWidget):



MyTable *dataSheet = new MyTable;//i have overloaded the QTableWidget too
MyTableItem *test = new MyTableItem("test");
dataSheet->setItem(2, 2, test);
QLineEdit *action = new QLineEdit;
connect(action, SIGNAL( textChanged ( const QString & ) ),dataSheet->item(2,2) , SLOT( setTextSlot ( const QString & ) ));

I get the following error:


error: no matching function for call to ‘MyWidget::connect(MyLineEdit*&, const char*, QTableWidgetItem*, const char*)’
/usr/include/qt4/QtCore/qobject.h:198: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
/usr/include/qt4/QtCore/qobject.h:313: bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const

I think I am close to make it work, but there's something wrong.

From the moment that this line works:


connect(action, SIGNAL( textChanged ( const QString & ) ), test, SLOT( setTextSlot ( const QString & ) ));

there must be a way to make this line work too:


connect(action, SIGNAL( textChanged ( const QString & ) ),dataSheet->item(2,2) , SLOT( setTextSlot ( const QString & ) ));

stampede
3rd February 2011, 02:13
Probably you haven't implemented the "item" method in your QTreeWidget subclass to return your custom items, so "item" still returns QTreeWidgetItem*, which is not a QObject and thus cannot be used in signal / slot mechanism.
If you want to go this way, one of solutions is - implement ' MyTable::item(int,int) ' to return ' MyTableItem* '.

fatecasino
3rd February 2011, 02:32
Did you mean this?


MyTableItem* MyTable::item ( int row, int column ) const
{
return item ( row, column );
}

It compiles fine, but I get segmentation fault because of this :(

the source code has something like this:

return tableItems.value(tableIndex(row, column));

but i don't know how to transform it to my class

stampede
3rd February 2011, 12:27
segmentation fault because of this
Yes, this is correct behaviour according to the implementation:)

Try to imagine what happens when you call

item(2,2);
...
( small hint: item(2,2) => { return item(2,2) => { return item(2,2) => ... } } )
Calling the same method with the same arguments over and over...

What you want to do is to call base class implementation of "item" from your class "item" method and convert the result to your datatype. So there are two more questions:
1) how to call base class implementation from derived class method ?
2) how to convert from base class pointer to derived class pointer at runtime ?

Can't help you more with this, because next step is to write ~30 more characters in your "item" implementation:p Believe me, you'll learn much more by doing this yourself ( there is great, free C++ book available online called "Thinking in C++" )