How to use removeRows with QStringListModel - qt

I have a QStringListModel which works ok, but then I need to delete all the rows from it from QML.
I would expect removeRowsfunction from Qt documentation work like that, but I don't know how to use it property.
removeRows(int row, int count, const QModelIndex &parent = QModelIndex())
I tried to use it like this:
myModel.removeRows(1, 1)
But I am getting thie error:
qrc:/Logger.qml:63: TypeError: Property 'removeRows' of object QStringListModel(0x337350) is not a function
Can someone explain how to use removeRows correctly? Thanks.

removeRows() is not invokable from QML. the solution is to make it invokable by creating a new class and overriding that method:
class StringListModel: public QStringListModel{
Q_OBJECT
public:
Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()){
return QStringListModel::removeRows(row, count, parent);
}
};
In the following link there is an example.

Related

QSqlQueryModel - How to add and delete rows?

I am making my model which inherits from QSqlQueryModel
#include <QSqlQueryModel>
class SqlQueryModelBorrowingUsers : public QSqlQueryModel
{
Q_OBJECT
//some class members
};
I also have a view that I set in BorrowingUsersWindow class and pass my model to that view.
in this view, i have two QPushButtons add record and delete record
class BorrowingUsersWindow : public QDialog
{
Q_OBJECT
//some class members
private:
SqlQueryModelBorrowingUsers *myModel; //my model
QTableView *tblViewUserData; //my view
QPushButton *bttAddRecord, *bttRemoveRecord; //I have a two buttons add and remove
};
Looking at the classes that QSqlQueryModel inherits from, I found
two functions in the QAbstractItemModel class
insertRow(int row, const QModelIndex &parent = QModelIndex())
removeRow(int row, const QModelIndex &parent = QModelIndex())
So the question is this. How can I implement adding and deleting rows with these two functions? Will someone give you a sample code?

QTableWidget with automatic restore of old cell value

I'm just getting started with QT, so please exercise a little patience...
I've an editable QTableWidget (actually a subclassing), and need to implement the following behavior.
When the user types a non acceptable value I would like:
1) to restore the original value;
2) to keep the focus in the cell and set it in edit mode.
I'm currently using the itemChanged SIGNAL, and a subclassing of QTableWidgetItem.
Which one is the best way to get what I need?
Any tip, suggestion or reference is really welcome.
If you think it as useful I can post some code.
Ciao
Alf.
I'm currently using the itemChanged SIGNAL...
You should subclass QStyledItemDelegate
class CustomTableDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CustomTableDelegate (QObject * parent = 0);
QWidget * createEditor (QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const;
bool editorEvent (QEvent *, QAbstractItemModel *, const QStyleOptionViewItem &, const QModelIndex &);
void setEditorData (QWidget *, const QModelIndex &) const;
void setModelData (QWidget *, QAbstractItemModel *, const QModelIndex &) const;
};
And implement validation inside setModelData.
To use custom delegate you need set it for your QTableWidget:
table->setItemDelegate (new CustomTableDelegate () );

Why is MyModel::data() not being called (subclassing QSqlQueryModel)

Hi I can't figure out why my data() function is never called when populating QTableView
I subclassed QSqlQueryModel. The header is like:
class TicketModel : public QSqlQueryModel
{
Q_OBJECT
public:
explicit TicketModel(QObject *parent = 0);
QVariant data(const QModelIndex &index, int role);
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
};
In the main window I set my model to the table
TicketModel *model = new TicketModel();
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model);
QSqlQuery *query = _tf->search(1);
model->setQuery(*query);
_ui->dashTable->setModel(proxyModel); // <<<<<<<<<<<<<< I setting model here too, didn't work
_ui->dashTable->setSortingEnabled(true);
_ui->dashTable->horizontalHeader()->setVisible(true);
_ui->dashTable->setSelectionBehavior(QAbstractItemView::SelectRows);
The TicketModel::headerData(...) is called but TicketModel::data(...) is never called when the table is created. Why? How can I get it to be called?
I hope I just overlooked something simple but I have been trying for a few hours to figure it out.
Thanks for the help!
You've got the signature wrong. You need a const.
QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const

emit dataChanged(createIndex(1,1),createIndex(1,1)) results in many ::data invocations

I have a QTableView and a corresponding instance of a child of QAbtractTableModel.
I was surprised to see that if my table model instance emits a dataChanged naming a single cell, the Qt framework will then issue a large number of calls to my table model's ::data() member function. The row/column range of those calls appears to cover the entire range of what is on the screen + some extra.
This is more than I expected. I would have thought that a dataChanged() that names a single cell would only result in ::data() calls requesting data for that cell. After all, that's the only cell that my table model said was changed. But the Qt framework appears to be very gregarious and inquires about all the cells.
I clearly have a broken understanding of the intent of the dataChanged() signal.
Is there a way to tell the QTableView to update one cell and one cell only without all the extra chatter sent to my table model?
UPDATE: Including code sample
The example here is a header, source, and a chunk of code to create the table. For me, the table displays with 12 columns and 29 rows. After the "issueEmit" invocation at the end, ::data will be invoked 1044 times all because of a dataChanged() signal for a single cell.
// Declaration
#include <QAbstractTableModel>
class SimpleModel : public QAbstractTableModel
{
Q_OBJECT
private:
bool _post_emit;
public:
explicit SimpleModel(QObject *parent=0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
void issueEmit();
};
// Implementation
#include <stdlib.h>
#include <stdio.h>
#include "simplemodel.h"
SimpleModel::SimpleModel(QObject *parent) : QAbstractTableModel(parent), _post_emit(false) { }
int SimpleModel::rowCount(const QModelIndex &parent) const {
return 100;
}
int SimpleModel::columnCount(const QModelIndex &parent) const {
return 100;
}
QVariant SimpleModel::data(const QModelIndex &index, int role) const {
if (role==Qt::DisplayRole) {
if (_post_emit) {
static unsigned s_calls=0;
s_calls++;
printf("Data calls: %d\n",s_calls);
}
return ((rand()%10000)/1000.00);
}
return QVariant();
}
void SimpleModel::issueEmit() {
_post_emit=true;
emit dataChanged(createIndex(1,1),createIndex(1,1));
}
// Usage
QTableView *table=new QTableView;
table->setMinimumSize(1200,900);
SimpleModel *model=new SimpleModel;
table->setModel(model);
table->show();
model->issueEmit();
QVariant QStandardItem::data ( int role = Qt::UserRole + 1 ) const [virtual]
Returns the item's data for the given role, or an invalid QVariant if there is no data for the role.
The argument is really the interesting thing here. Each item in a model holds a number of QVariants, these QVariants maintain different information about the item.
These Variants are all assigned roles. Any time you emit that data has changed the model must redraw the item. To redraw the item it must look at many different pieces of data (small excerpt included below)
Roles describing appearance and meta data (with associated types):
Constant Value Description
Qt::FontRole 6 The font used for items rendered with the default delegate. (QFont)
Qt::TextAlignmentRole 7 The alignment of the text for items rendered with the default delegate. (Qt::AlignmentFlag)
Qt::BackgroundRole 8 The background brush used for items rendered with the default delegate. (QBrush)

QTableView - Not Getting Selection Changed Signal

I am fairly new to QT, and am having trouble understanding how the QTableView selection changed signal is handled. I have setup a window with an openGL widget and a QTableView. I have a data model class that is correctly populating the tableview, so I added a public slot to that class:
class APartsTableModel : public QAbstractTableModel
{
public:
AVehicleModel *vehicle;
explicit APartsTableModel(QObject *parent = 0);
//MVC functions
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &paret) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
public slots:
void selectionChangedSlot(const QItemSelection &newSelection,
const QItemSelection &oldSelection);
};
When I am ready to show the window with the table view, I allocate/initialize it like this:
//create the display view
AStarModelView *displayWindow = new AStarModelView(this,
starModel->vehicle);
//create the datamodel for the table view
APartsTableModel *dataModel = new APartsTableModel(displayWindow);
dataModel->vehicle = starModel->vehicle;
//create selection model for table view
QItemSelectionModel *selModel = new QItemSelectionModel(dataModel);
displayWindow->materialsTable->setSelectionModel(selModel);
//setup model and signal
displayWindow->materialsTable->setModel(dataModel);
connect(selModel,
SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
dataModel,
SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &)));
//show the view
displayWindow->show();
When I set a breakpoint in the implementation of the slot function, I never hit it. I've also tried not allocating a new QItemSelectionModel, but that didn't work either. I'm really not sure what I'm doing wrong here.
When you call setModel() on the view, your locally allocated QItemSelectionModel is getting replaced by one created by the view. You shouldn't have to create your own selection model anyway. Just change your connect to
connect(displayWindow->materialsTable->selectionModel(),
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
dataModel,
SLOT(selectionChangedSlot(const QItemSelection&, const QItemSelection&)));
What's the first thing you should check in QT when signals/slots don't seem to be working correctly? That your class has the Q_OBJECT macro in it. Added this to the APartsTable class definition, and now I'm hitting the breakpoint.
When does Friday get here?
Just to pull the answer out of the discussion:
What's the first thing you should check in QT when signals/slots don't
seem to be working correctly? That your class has the Q_OBJECT macro
in it. Added this to the APartsTable class definition, and now I'm
hitting the breakpoint
.
virtual Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const
must return Qt::ItemIsSelectable | otherFlags

Resources