create a table in Qt and fill it by the user - qt

i want to create an Qt application containing a table of 3 columns and n row, the user will choose the number of row by putting it in the edit button and the table will have 3 columns and the number given by the user. then fill it with element
i have search a lot but only found how to fill the able with sql data,
please is anybody having an idea?
here is what i did so far, i have fixed the number of rows and columns but it is not what i want, besides, i want to use either QtableWidget or QtavleViewItem
int n;
n = ui->spinBox->value();
QStandardItemModel *model = new QStandardItemModel(n,3,this); //2 Rows and 3 Columns
model->setHorizontalHeaderItem(0, new QStandardItem(QString("x")));
model->setHorizontalHeaderItem(1, new QStandardItem(QString("y")));
model->setHorizontalHeaderItem(2, new QStandardItem(QString("z")));
ui->tableView->setModel(model);

you can go through the elements in a QTableView and do things with them:
for(int r=0; r<N_ROWS; r++)
{
for(int c=0; c<N_COLS; c++)
{
QModelIndex index = ui->tableView->model()->index(r,c, QModelIndex());
// Do something with the QVariant that index.data() returns
qDebug() << r << c << index.data().toString();
}
}
Regards.

Related

Dispaly three items of QStringList in one QtableWidget element

I have a binary vector (it is in hex)
For Example -
x={0x06, 0xfc, 0x47}
I want to save it in a QStringList and then read it from the list and display all of them in one element of QTableWidget. How can I do this? I did this previously with a for loop but it only displays the last vector element (0x47) in the table.
Thanks.
You can do it like this:
QStringList list;
for(int i = 0; i < vector.size(); ++i)
{
list.append(QString::number(vector[i], 16));
}
// i - row, j - column in function join put your separator(for example "\n" if you want all items in new row)
ui->tableWidget->setItem(i,j, new QTableWidgetItem(list.join("\n"));

How to set data source for a list view to contain custom data ? (and associate with QTableView)

I am trying to get listview and tableview working together.
The listview must be used for display, the tableview must be used for editing data. The tableview is created on demand in a popup widget (and it may never be needed).
I populate the listview, on start, from a text file - each row a line, with 2 entries separated by a tab. Easy.
The tableview will have to edit 2 columns separately... also, on listview click, I must be able to retrieve the first part of the split...
I have created a model subclass of QStringListModel.
QListView *m_myView = new QListView();
StringList *m_myList = new StringList();
QTextStream in(&myFile);
while (!in.atEnd())
{
QString temp = in.readLine();
if(!temp.isEmpty())
m_myList->append(temp);
}
myFile.close();
m_myView->setModel(m_myList);
where
class StringList : public QStringListModel
{
public:
void append (const QString& string)
{
insertRows(rowCount(), 1);
QModelIndex m = index(rowCount() - 1);
setData(m, string, Qt::EditRole);
QStringList splist = string.split('\t');
setData(m, splist.at(0), Qt::ToolTipRole);
if(splist.size() > 1)
setData(m, splist.at(1), Qt::StatusTipRole);
else
setData(m, "", Qt::StatusTipRole);
qDebug() << data(m, Qt::EditRole).toString()
<< data(m, Qt::ToolTipRole).toString()
<< data(m, Qt::StatusTipRole).toString();
}
};
The EditRole displays correctly, the others display empty strings.
It seems that QStringListModel is incapable of storing anything except EditRole.
So I am left with 2 options - either do the split on each selection, and also when creating the table view, or - what I would like to try but don't know how - create a QStandardItemModel that can act as data sources for both the listview and the tableview, and can easily retrieve the partial data I require on click.
I thought I can simply use it to set the data on listview (like they do here).
QListView *m_myView = new QListView();
QStandardItemModel *m_myList = new QStandardItemModel();
QTextStream in(&myFile);
int r = 0;
while (!in.atEnd())
{
QString temp = in.readLine();
if(!temp.isEmpty())
{
QStringList splist = temp.split('\t'); // assume I know there will be 2 strings always
QStandardItem *item = new QStandardItem(splist.at(0));
m_myList->setItem(r, 0, item);
QStandardItem *item1 = new QStandardItem(splist.at(1));
m_myList->setItem(r, 1, item1);
++r;
}
}
myFile.close();
m_myView->setModel(m_myList);
connect(m_myListView, SIGNAL(clicked(QModelIndex)),
this, SLOT(listChangedSlot(QModelIndex)));
But this will only set the first string in the listview, I really need both, and I still don't know how to retrieve the data
void listChangedSlot(QModelIndex index)
{
qDebug() << m_myList->item(index.row(), 0)->data().toString()
<< m_myList->item(index.row(), 1)->data().toString();
} // shows empty strings
Or...
In the loading section, try:
if(!temp.isEmpty())
{
QStringList splist = temp.split('\t');
splist.append(QString()); // so I don't need to test
QStandardItem *item = new QStandardItem(temp);
m_myList->setItem(r, 0, item);
QModelIndex idx = m_myList->index(r, 0);
QMap<int, QVariant> roles;
roles.insert(Qt::UserRole + 1, QVariant(splist.at(0)));
roles.insert(Qt::UserRole + 2, QVariant(splist.at(1)));
roles.insert(Qt::DisplayRole, QVariant(temp));
m_myList->setItemData(idx, roles);
++r;
}
This works - displays fine and gets the correct content on click - but seems to be unusable for the tableview.
(And seems I am doing twice the work, with setItem and setItemData - so technically storing the content 3 times).
How can I get my listview have a datasource with 2 string items, show both, be able to set it on a tableview, and be able to retrieve the first item on click ?
I figured out a way to share the data source between the listview and tableview:
I create 3 columns - column 0 with the combined components, and columns 1 and 2 with the separated components.
The listview will display only column 0. For tableview, I will hide column 0.
The data I require for processing will be stored in columns 1 and 2. user edit of the data in tableview will require, upon accepting changes, the edit of corresponding column 0.

QT QStandardItemModel - how to store a list of items in one cell

I am new with QT, so I'll apprciate any help.
In my application, I'm creating a QStandardItemModel with rows and columns. Now I want to save in one cell a list of QStrings - but I dont know how to do that.
I've tried to write this code:
QStandardItem* dataRecords = new QStandardItem();
QList<QStandardItem* > list;
QList<QString>::const_iterator dataRecord;
for( dataRecord = i.value()->begin(); dataRecord != i.value()->end(); ++dataRecord )
list << new QStandardItem((*dataRecord));
dataRecords->appendRows(list);
model->setItem(row, 3, dataRecords);
i is a QList of QString.
Now, I dont know how can I access abd retrive the QString values from the model.
Can anyone please help me? or suggest me another way to do that?
Thanks!
You should read some docks about Model\View proggramming in Qt
To access data stored in model you should use: QVariant QStandardItemModel::data ( const QModelIndex & index, int role = Qt::DisplayRole )
To get QModelIndex for particular cell use: QModelIndex QStandardItemModel::index ( int row, int column, const QModelIndex & parent = QModelIndex() )
Some code example...
QModelIndex superIndex = model->index(i,j);
QString superData= model->data(superIndex).toString();

How to get the texts of all items from QListWidget in Qt?

How can I get the texts of all the widgets in a QListWidget as a QList<QString>?
I can get the list of widget items like this:
QList<QListWidgetItem *> items =
ui->listWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard);
But that's not exactly what I want, I'd like the list of the widget text() properties.
There is no built-in function for that, you'll need to do it manually.
QList<QString> texts;
foreach(QListWidgetItem *item, items)
texts.append(item->text());
Or something like that.
int c = ui->listWidget->count();
for (int i = 0; i < c ; ++i){
QString s = QString::number(i);
QModelIndex *model_index = new QModelIndex(ui->listWidget->model()->index(i,0) ); //0th column since we have one cloumn in listwidget
QString q= model_index->data(Qt::DisplayRole).toString();
qDebug()<<q;
}

how to get selected rows in QTableView

After watching many threads about getting selected rows numbers, I am really confused.
How do you get ROW numbers in QTableView using QStandardItemModel I used below selection model and behavior as
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::SingleSelection);
and if you have your own way of selecting can you explain how it works.
Thanks for the help!
The method selectionModel() return a QItemSelectionModel.
You can use QItemSelectionModel class to check/change/other selection(s)
Example:
QItemSelectionModel *select = table->selectionModel();
select->hasSelection() //check if has selection
select->selectedRows() // return selected row(s)
select->selectedColumns() // return selected column(s)
...
Check selectedRows method of the QItemSelectionModel Class .
QModelIndexList selection = yourTableView->selectionModel()->selectedRows();
// Multiple rows can be selected
for(int i=0; i< selection.count(); i++)
{
QModelIndex index = selection.at(i);
qDebug() << index.row();
}
try:
QModelIndexList indexList = yourTableView->selectionModel()->selectedIndexes();
int row;
foreach (QModelIndex index, indexList) {
row = index.row();
....
}
Since you use
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::SingleSelection);
so only one row can be selected each time, then you can try this:
auto rowList = yourTableView->selectionModel()->selectedRows();
if(rowList.count() > 0)
int rowNumber = rowList.constFirst().row();
else
// no row is selected

Resources