Filling column in List Contol with setItemText - c++

I'm trying to fill my column in List control (m_listCtrl) in MFC. I want to do it in that way :
void CMy1domacanalogaRadixDlg::sort()
{
// some code here
for (int i = 0; i <size; i++)
{
counter++;
a[i] = b[i];
niz.Format(_T("%d"), a[i]);
// here choose column and add numbers
m_listCtrl.SetItemText(i,counter,niz);
}
}
I want to create columns dynamically, because I want to add every for loop iteration in own column, but the problem is that I need to press button "Sort" on my form twice to display numbers in column. It's all work fine, I have all numbers in column but not on first button press. Thanks for help.

Related

How to set a new item in tabview Qt, and save the previous ones

When I use Qt tableView, I can just set item in the first row. When I click add, it will cover the former, but not set a new item. Maybe my slot function is incorrect. But I don't know how to handle it.
void Widget::on_addButton_clicked()
{ int i = 0;
EditDialog editDialog(this);
if(editDialog.exec() == 1)
{
model->setItem(i,0,new QStandardItem(editDialog.getID()));
model->setItem(i,1,new QStandardItem(editDialog.getPriority()));
model->setItem(i,2,new QStandardItem(editDialog.getTime()));
}
i++;
}
Please, have a look into doc. QStandardItemModel::setItem():
Sets the item for the given row and column to item. The model takes ownership of the item. If necessary, the row count and column count are increased to fit the item. The previous item at the given location (if there was one) is deleted.
(Emphasizing is mine.)
If a row shall be inserted before end of table (e.g. as first), then it's necessary to do this explicitly.
This can be achieved by calling QStandardItemModel::insertRow() before setting the items.
This could e.g. look like this:
// fills a table model with sample data
void populate(QStandardItemModel &tblModel, bool prepend)
{
int row = tblModel.rowCount();
if (prepend) tblModel.insertRow(0);
for (int col = 0; col < NCols; ++col) {
QStandardItem *pItem = new QStandardItem(QString("row %0, col %1").arg(row).arg(col));
tblModel.setItem(prepend ? 0 : row, col, pItem);
}
}
I took this from an older post of mine. The complete sample can be found in my answer to SO: Stop QTableView from scrolling as data is added above current position.

How to efficiently copy contents between two list controls

I want to copy rows from one List Control to another List Control. I am only able to copy them by sub item. I think this is not very efficient. There must be a method to copy the content by rows. The following is my code that copies content one sub item at a time.
CString CurItem, tem, copystr;
int j = 0;
m_combo_list.GetLBText(m_combo_list.GetCurSel(), CurItem);
for (int i = 0; i < m_list.GetItemCount(); i++) {
tem = m_list.GetItemText(i, 0);
if (CurItem == tem) {
m_report_list.InsertItem(j, _T(""));
for (int k = 0; k < 14; k++) { // 14 items per row.
copystr = m_list.GetItemText(i, k);// get one item per time from one list control.
m_report_list.SetItemText(j, k, copystr); // this is another list control. Copy the item to this list control.
}
j++;
}
}
Could anyone give a method to replace the for loop by copy a row from m_list to m_report_list directly? I think such a way must save a lot of time.

Get Index of Item Text in MFC CListCtrl

I've got a CString with a Text that also is an Item Text of my CListCtrl. For example:
CString m_SearchThisItemText = _T("Banana");
And in my CListCtrl
m_List.SetItemText (1, 1, _T ("Banana"));
Now I want to find out, on which Index the Text is.
CListCtrl::FindItem
doesnt work. It only searches the name of the Item, not the Text.
I also tried this
for (Index= 0; dlg.GetSearchContentText () == m_List.GetItemText (Index, Spalte); Index++)// HIER IST NOCH EIN FEHLER.
{
if (dlg.GetSearchContentText () == m_List.GetItemText(Index, Spalte))
{
m_List.SetItemState (Zeile, LVIS_SELECTED, LVIS_SELECTED);
m_List.SetFocus();
}
}
But it doesnt work. It stops at Index 0
Can anyone help me, how to find out on which Item the text is.
I hope you understand my question.
Iterate all the items and search in the column you want:
int nCol = 1; // to search in the second column (like your question)
CString m_SearchThisItemText = _T("Banana");
for (int i = 0; i < m_List.GetItemCount(); ++i)
{
CString szText = m_List.GetItemText(i, nCol);
if (szText == m_SearchThisItemText)
{
// found it - do something
break;
}
}
If you mean that you have a list view with several columns and you want to search in other columns than the first one, then FindItem won't help you. You'll have to explicitly write the find code yourself. You must iterate over all the rows in the list, and for each column of a row call GetItemText and compare what you get with the text you have.

How to delete all rows from QTableWidget

I am trying to delete all rows from a QTableWidget . Here is what I tried.
for ( int i = 0; i < mTestTable->rowCount(); ++i )
{
mTestTable->removeRow(i);
}
I had two rows in my table. But this just deleted a single row. A reason could be that I did not create the the table with a fixed table size. The Qt Documentation for rowCount() says,
This property holds the number of rows in the table.
By default, for a table constructed without row and column counts,
this property contains a value of 0.
So if that is the case, what is the best way to remove all rows from table?
Just set the row count to 0 with:
mTestTable->setRowCount(0);
it will delete the QTableWidgetItems automatically, by calling removeRows as you can see in QTableWidget internal model code:
void QTableModel::setRowCount(int rows)
{
int rc = verticalHeaderItems.count();
if (rows < 0 || rc == rows)
return;
if (rc < rows)
insertRows(qMax(rc, 0), rows - rc);
else
removeRows(qMax(rows, 0), rc - rows);
}
I don't know QTableWidget but your code seems to have a logic flaw. You are forgetting that as you go round the loop you are decreasing the value of mTestTable->rowCount(). After you have removed one row, i will be one and mTestTable->rowCount() will also be one, so your loop stops.
I would do it like this
while (mTestTable->rowCount() > 0)
{
mTestTable->removeRow(0);
}
AFAIK setRowCount(0) removes nothing. Objects are still there, but no more visible.
yourtable->model()->removeRows(0, yourtable->rowCount());
QTableWidget test;
test.clear();
test.setRowCount( 0);
The simple way to delete rows is to set the row count to zero. This uses removeRows() internally.
table->setRowCount(0);
You could also clear the content and then remove all rows.
table->clearContents();
table->model()->removeRows(0, table->rowCount());
Both snippets leave the headers untouched!
If you need to get rid of headers, too, you could switch from clearContents() to clear().
In order to prevent an app crash, disconnect all signals from the QTableView.
// Deselects all selected items
ui->tableWidget->clearSelection();
// Disconnect all signals from table widget ! important !
ui->tableWidget->disconnect();
// Remove all items
ui->tableWidget->clearContents();
// Set row count to 0 (remove rows)
ui->tableWidget->setRowCount(0);
Look this post : http://forum.qt.io/topic/1715/qtablewidget-how-to-delete-a-row
QList<QTableWidgetItem*> items = table.findItems(.....);
QMap<int, int> rowsMap;
for(int i = 0; i < items.count(); i++{
rowsMap[items.at(i).row()] = -1; //garbage value
}
QList<int> rowsList = rowsMap.uniqueKeys();
qSort(rowsList);
//Now go through your table and delete rows in descending order as content would shift up and hence cannot do it in ascending order with ease.
for(int i = rowList.count() - 1; i >= 0; i--){
table.removeRow(rowList.at(i));
}
You can just add empty item model (QStandardItemModel) to your QTableView (myTableView):
itemModel = new QStandardItemModel;
ui->myTableView->setModel(itemModel);
In python you can just set the rowCount to zero and that'll work!
tableWidget.setRowCount(0)
This code is tested with PySide6. Hope it will work for PyQt5 and PyQt6 too.
Your code does not delete last row.
Try this one.
int totalRow = mTestTable->rowCount();
for ( int i = 0; i < totalRow ; ++i )
{
mTestTable->removeRow(i);
}
In your code, on the first time, rowCount() have value 2 and value of the i is 0, so its delete 1st row,
But on the second time value of i incremented with 1, but rowCount() return the updated row count which is now 1, so, it does not delete the last row.
Hope now you ll be clear.
Removes all items not in the headers from the view. This will also remove all selections. The table dimensions stay the same.
void QTableWidget::clearContents()
Removes all items in the view. This will also remove all selections and headers.
void QTableWidget::clear()
This works for me:
for i in reversed(range(self.tableWidget.rowCount())):
self.tableWidget.removeRow(i)

QTableWidget update items

I’m having trouble with updating QTableWidgetItems. I don’t understand what I’m doing wrong :(
code and explanation.
Step by step problem.
at first insertion = OK, all first cells are filled.
updating firstly inserted items = OK, all first cells are updated.
at second insertion = OK, all second cells are filled.
updating second inserted items = OK, all second cells are updated.
updating first inserted items = FAIL, all first cells are updated, but NEXT cell’s first table is empty. WHY?
Code:
void MainWindow::fillTable(QList<QByteArray> Info)
{
int Row = ui->clientsList->rowCount() - 1; //Starts from 0.
//Check if client row already exists.
for(int i = Row; i >= 0; i--)
{
if(ui->clientsList->item(i, 0)->text().contains(QString(Info[1])))
{
//Update row.
for(int u = 0; u < Info.count() - 1; u++)
{
ui->clientsList->setItem(i, u, new QTableWidgetItem(QString(Info[u + 1])));
}
return; //avoid new row insertion.
}
}
//Insert new row.
Row = ui->clientsList->rowCount() + 1;
ui->clientsList->setRowCount(Row);
for(int i = 0; i < Info.count() - 1; i++)
{
//Fill rows.
ui->clientsList->setItem(Row - 1, i, new QTableWidgetItem(QString(Info[i + 1])));
}
}
Not full solution yet, but few comments:
1.There may be memory leak in line
ui->clientsList->setItem(i, u, new QTableWidgetItem(QString(Info[u + 1])));
why not use
ui->clientsList->item(i, u)->setText(QString(Info[u + 1]));
which is safer and more clear.
2.My understanding is you are relying on the fact that Info has same length as the row length is, perhaps it worth to add check for that?