tags:

views:

1851

answers:

5

I want to write an application that can access a table in the database. I took QSqlTableModel as model component for the table.

The problem with the QTableView is that it seems to have no method that returns the currently selected record in the table so i took the QTableWidget class which interhits QTableView.

But when i try to set the model to this table widget with ->setModel() i get the following error message:

c:/Qt/qt/include/QtGui/../../src/gui/itemviews/qtablewidget.h:337: error: `virtual void QTableWidget::setModel(QAbstractItemModel*)' is private.

The message says that the method "setModel" is private. Looking into the documentation tells me that it is public.

What can I do?

A: 

it is private in QTableWidget

class Q_GUI_EXPORT QTableWidget : public QTableView
{
...
...
private:
    void setModel(QAbstractItemModel *model);
...

it is public in QAbstractItemView

so you cant call this function from here...

check qtablewidget.h in include\Qt\qtablewidget.h

maybe it is not a good answer but at least it shows why it is not working...

ufukgun
A: 

QTableWidget:Details

The QTableWidget class provides an item-based table view with a default model.

Table widgets provide standard table display facilities for applications. The items in a QTableWidget are provided by QTableWidgetItem.

If you want a table that uses your own data model you should use QTableView rather than this class.

The widget class handles the model itself, if you want to use your own model use the View class.

You are correct that there does not seem to be methods for knowing the selection for the TableView or SQLModel. You could derive your own class from the TableView and track the current selection through the selectionChanged slot.

OR

Use the QTableView::selectionModel() and call selection(). This is similar to mmutz's answer. Be sure to read that code for the gory details of actually getting to the record.

Jesse
Careful. You don't want `selectionModel` here: that's the type used to handle selecting items in the view by, e.g. using Shift-click. The internal data model is simply the `model` property of a view.
quark
+1  A: 

The method is public at the level of QAbstractItemView but QTableWidget has a built-in model which you can't change.

To get the selection, you must call selectedItems() (which is again a method of QAbstractItemView and not QTableView which is why you missed it in the docs).

Aaron Digulla
I need to use QTableView because of public setModel() function, but QTableView hasnt selectedItems() function.P.S. Sorry for my English.
crew4ok
Like Aaron said, selectedItems() is a part of QTableView - it's a part of the base class QAbstractItemView.
swongu
I do not see selectedItems under QAbstractItemView either: http://doc.trolltech.com/4.5/qabstractitemview-members.html
Jesse
There is a typo above: It should say that QTableWidget has a built-in model, not QTableView.
Ropez
@Ropez: Thanks, fixed.
Aaron Digulla
+3  A: 

As others have noted, it's not QTableWidget that you want. It's indeed QTableView. Getting the records is then done like this:

static QList<QSqlRecord> selected_records( const QTableView * tv ) {
    // make sure we're really dealing with what we think we're dealing with:
    assert( static_cast<QSqlTableModel*>( tv->model() )
            == qobject_cast<QSqlTableModel*>( tv->model() );
    const QSqlTableModel * const tm = static_cast<QSqlTableModel*>( tv->model() );
    const QModelIndexList mil = tv->selectionModel()->selectedRows();
    QList<QSqlRecord> result;
    Q_FOREACH( const QModelIndex & mi, mil )
        if ( mi.isValid() )
            result.push_back( tm->record( mi.row() ) );
    return result;
}

If, OTOH, you are working in a slot connected to the - say - clicked(QModelIndex) signal of QTableView (really: QAbstractItemView), then this code is what you want:

void slotClicked( const QModelIndex & mi ) {
    // make sure we're really dealing with what we think we're dealing with:
    assert( static_cast<QSqlTableModel*>( tableView->model() )
            == qobject_cast<QSqlTableModel*>( tableView->model() );
    const QSqlRecord rec = static_cast<QSqlTableModel*>( tableView->model() )
               ->record( mi.row() );
    // use 'rec'
}

Yes, Qt could have that built-in, and esp. QSqlTableModel could have a more convenient way to map a QModelIndex back to a QSqlRecord, but there you go.

As I understand, I have to use it with clicked() signal.But when i'm checking if the QList is empty I get that it's empty.=/
crew4ok
If you use `QAbstractItemView::clicked(QModelIndex)`, the `QModelIndex` is passed as a signal argument. The above code is for the case that you want to see what the selected records are. In the `clicked()` case, you just need the two lines inside the `Q_FOREACH`, with `mi` being the `QModelIndex` coming from the signal.
Thanks, you answered my question=).
crew4ok
A: 

I only used the model-view architecture once, but I'll try to give you some general insight in that architecture, because it seems to me you don't understand it very well yet. So this will probably be incomplete and simplified, but hopefully somewhat correct.

If you work with a view, you can provide you're own model. If you work with a widget, then you dont work with a qt model, but insert items yourself. Preferably you work with a model to decouple things (so you can have more than one view for the same model, or change the model later on, ...)

When you use a model the view will itself knows how to ask the model you provide to populate the view (using the data function). There are several ways to get a selection from this view: I have handled it by connecting the clicked signal, that the view emits when the user clicks in the view, to a slot function i wrote myself. The clicked signal provides an index of the table/list that I map to an item in my model in that slot function.

There are probably more ways to do it, but thats how I did it and it works fine.

To get a general grasp on the qt model-view architecture:

http://doc.trolltech.com/4.5/model-view-programming.html

Emile Vrijdags