PDA

View Full Version : Model/View Programming -- Signals



KjellKod
4th February 2006, 16:16
Hi,

I am working with a QTableView with a custom delegate. In the createEditor function for the delegate I either create QLineEdit or QComboBox items. Can I connect to the signals that these items are emiting when they are used?

Example: The QComboBox emits activated ( int index ) when an item in the QComboBox is activated.

Do I have to subclass QTableView, connect the wanted signal from the returned widget from widget* createEditor? or can someone recommend another better approach?

Everall
4th February 2006, 17:03
You can use a QtableView without subclassing.

set the delegate of your view using setItemDelegate(yourDelegate)
Connections to your signals are already set up now.

Cheers

Xagen
4th February 2006, 17:08
Hi,

I am working with a QTableView with a custom delegate. In the createEditor function for the delegate I either create QLineEdit or QComboBox items. Can I connect to the signals that these items are emiting when they are used?

Example: The QComboBox emits activated ( int index ) when an item in the QComboBox is activated.

Do I have to subclass QTableView, connect the wanted signal from the returned widget from widget* createEditor? or can someone recommend another better approach?

Can you show the code please?
I'm very interested in code like this.
Thanks!

Everall
4th February 2006, 17:28
something like :

QTableView* myView;
myView->setItemDelegate(yourDelegate);

The delegate has signals like closeEditor, that is connected to the view's closeEditor Slot automatically.
If you want custom slots then you'll have to make the connections yourself.

What code do you have already, maybe we can fill in the gaps.


Cheers

Xagen
4th February 2006, 18:40
I know how to realize delegating items.
I wanted to see the code where the delegate item is QTextEdit and when user presses Enter button he can continue editing text.

Sorry, for my English.

KjellKod
4th February 2006, 20:44
Hi again.

The problem is not in creating the delegate. I've one and it works. The problem is that that in the QTableView I use items, sometimes QLineEdit and sometimes QComboBox items that are created in the delegate. The issue is really that I can't seem to getI the QLineEdit's and QComboBox's specific signals that are emitted when the user is doing things in them (selecting item, etc).

Code example: Sorry if I'm writing this, maybe it's better to include files?


UIQtCookBook::setupItemViews()
{
/* Other code here... setting the Model for the view etc */
// Setting the delegate for the view
IngredientTableDelegate *ingredientTableDelegate = new IngredientTableDelegate();
ingredientsTableView->setItemDelegate( ingredientTableDelegate);
}

// Other file.
// IngredientTableDelegate is subclass of QItemDelegate
//
QWidget* IngredientTableDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index ) const
{
QWidget* editor = 0;

if( checkIfCombo() )
{
editor = new QComboBox (parent);
const QAbstractItemModel* model = index.model();
QVariant value = model->data( index, Qt::DisplayRole );

// Add the list of measurements to the QComboBox
QString measurement= value.toString();
QComboBox* box = new QComboBox( parent );
box->addItems( m_measurements );
editor = box;
// The connection below does not work
connect(box, SIGNAL(activated(int)), this, SLOT(setTestPrintout(int)));
}
else
{
editor = new QLineEdit( "-na-", parent);
const QAbstractItemModel* model = index.model();
QVariant value = model->data( index, Qt::DisplayRole );
QLineEdit* editLine = new QLineEdit(parent);
editor = editLine;
}

editor->installEventFilter(const_cast<IngredientTableDelegate*>(this));
return editor;
}



So far so good. But what I really what to do is to catch the activated signal from QComboBox items, basically I wan't to call a specific function when a certain value in the QComboBox is chosen. I do not seem to be able to do that.

I.e. the bottom line is. How can I connect the signals from the dynamically created QWidgets in createEditor above to another function in this class. I've tried (naive approach?) to do it in the createEditor function, but I do not get the expected result (see the comment in the code --- the printout function is never called)

Everall
4th February 2006, 20:59
when user presses Enter button he can continue editing text.
Do you mean you want to go to the next cell when pressing Enter?

If that's the case you'll have to subclass the delegates eventFilter. When you press enter you emit the closEditor signal and use the EditNextItem flag. This will open the next cell for editing.


bool autoSqlRelationalDelegate::eventFilter(QObject *object, QEvent *event)
{
QWidget *editor = ::qobject_cast<QWidget*>(object);
if (!editor)
return false;
if (event->type() == QEvent::KeyPress) {
switch (static_cast<QKeyEvent *>(event)->key()) {
case Qt::Key_Tab:
emit commitData(editor);
emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
return true;
case Qt::Key_Backtab:
emit commitData(editor);
emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem);
return true;
case Qt::Key_Enter:
emit commitData(editor);
emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
case Qt::Key_Return:
emit commitData(editor);
emit closeEditor(editor,delegate::EditNextItem);
return true;;
...


Cheers

KjellKod
4th February 2006, 21:01
Sorry guys, but Xagen it's a bit confusing having different questions in the same thread!!! Sorry for the rebuke. But maybe it's easier to have two threads since we're not trying to achieve the same thing or?

Everall
4th February 2006, 21:10
sorry KjellKod I didn't notice the questions came from 2 different people.
And yes it's a little confusing.

I'll lhave a look into your code.

cheers,

Everall

KjellKod
4th February 2006, 21:14
Thanks Everall -- I'll be away for a few hours but I'll look back into this forum later. Any help is most appreciated :)

KjellKod
4th February 2006, 21:23
Hmmm. I found a Trolltech example that is almost identical to what I'm doing.
http://doc.trolltech.com/4.1/widgets-icons.html
--- I'll read through that example and see what I'm missing in the picture

Everall
4th February 2006, 21:43
But what I really what to do is to catch the activated signal from QComboBox items, basically I wan't to call a specific function when a certain value in the QComboBox is chosen. I do not seem to be able to do that.


Here is an idea:
If you choose an item in the combobox then the value of the cell is set in the view.

the view emits the activated(QmodelIndex& index) signal. You can connect it with the views datachanged(index, index) slot in the constructor of the view.

When you reimplement the datachanged slot you could determine where the signal comes from with sender() to determine if the signal comes from the combobox.

Hope this helps

KjellKod
5th February 2006, 00:37
Problem solved!
Thanks to that I'm a little rusty with Qt programming I guess and that the signal slot mechanism is very similar to the signal mechanism we use at work I got a little confused. Thanks for the great help though :) it was super to get some feedback and it did put me on the right track by just giving me the reason to look elsewhere for the solution.

Oh, and what the solution was. Heh, almost ashamed to say it, but I had not declared
the setTestPrintout(int))); as a slot.

I.e I changed:


void setEditable2(int test);

to

private slots:
void setEditable2(int test);

Xagen
5th February 2006, 08:54
Sorry guys, but Xagen it's a bit confusing having different questions in the same thread!!! Sorry for the rebuke. But maybe it's easier to have two threads since we're not trying to achieve the same thing or?

Sorry! I wasn't attentive....

wysota
5th February 2006, 21:30
Oh, and what the solution was. Heh, almost ashamed to say it, but I had not declared
the setTestPrintout(int))); as a slot.


That's why it is good to look at the console while writing the code. Qt surely warned you that such a slot doesn't exist.

Great that you managed to go through with it.

KjellKod
5th February 2006, 23:53
That's why it is good to look at the console while writing the code. Qt surely warned you that such a slot doesn't exist.
Nope, no such thing. I had to re-make my error and re-compile & re-run the program just to test it to see if you were right, but no. Too bad it didn't have that though.

jacek
6th February 2006, 00:01
I had to re-make my error and re-compile & re-run the program just to test it to see if you were right, but no.
Add "CONFIG += console" to your .pro file and try again.

KjellKod
7th February 2006, 17:36
Add "CONFIG += console" to your .pro file and try again.
Jacek thank you :) that worked great.
With Qt configured in debug mode and then re-generating Makefile, re-compiling and re-running the program I managed to trigger the wanted warning message:


Object::connect: Connecting from COMPAT signal (QTabWidget::currentChanged(QWidget*)).
createEditor called
Object::connect: No such slot IngredientTableDelegate::setEditable2(int)

I'll make sure that I always keep doing this with debug and console enabled :cool:
Muchas gracias