I'm trying to populate a wxListCtrl but after trying various methods can't seem to be able to populate it with items.
Basically, I want a list control that would have three columns with headings and will show values in rows. But I've tried InsertItem, SetItem, or InsertColumn methods but am only able to show the column headings but not the row data. Any help will be greatly appreciated! Thanks in advance!
You can add columns like this:
int column_width = 90;
my_list_ctrl->InsertColumn(0, L"ColumnText", wxLIST_FORMAT_LEFT, column_width);
You can add items like this:
int image_index = 0;
long list_index = my_list_ctrl->InsertItem(0, L"My Item text", image_index);
You can set the text of the subitems like this:
int column_index = 1;
my_list_ctrl->SetItem(list_index, column_index, L"Text");
You can setup an image list for your list like this:
my_list_ctrl->SetImageList(&img_list, wxIMAGE_LIST_SMALL);
Related
I need to search rows through a QTableWidget. Each of the rows in the table contains a field with date and I need to show only rows that are within a specified date interval based on user input. Here is my function:
void nvr::sort()
{
QTableWidget* tabela = this->findChild<QTableWidget*>("NCtable");
QDateEdit* c1 = this->findChild<QDateEdit*>("c1");
QDateEdit* c2 = this->findChild<QDateEdit*>("c2");
// user specified ranges for date
QDate date1 = c1->date();
QDate date2 = c2->date();
//row numbers in table
int rowsNum = tabela->rowCount();
// hide all rows
for(int z = 0; z < rowsNum; z++) {
tabela->hideRow(z);
}
// show only rows that are within range
for(int z = 0; z < rowsNum; z++) {
QDateTime dateTime = QDateTime::fromString(tabela->item(z,2)->text(),"dd.MM.yyyy hh:mm");
QDate date = dateTime.date();
//date compares
if ( (date1.operator <=(date)) && (date2.operator >=(date) ) ) {
tabela->showRow(z);
}
}
}
This works fine if i have 200 rows. But when i have 30 000 rows and i surely will, the gui freezes because i suppose the function executes very slow. Any suggestions for faster execution?
It is hard to reproduce your problem, but here is the approach I would take:
Create a custom class to store the data of one row, let's call it
DataRow.
Store those in a QVector<DataRow>, that you can sort by Date1 for example.
Loop through this QVector<DataRow> and find the elements that correspond to the criteria.
Add those DataRow to a class derived from QAbstractItemModel.
Show this model derived from QAbstractItemModel with a QTableView.
QTableWidget is heavyweight and was not really built for speed. It's really convenient to build something quickly with few elements though.
QTableView is the one you want, with a custom model inherited from QAbstractItemModel.
Then, when the user requests a new input, you could just wipe the model and restart the process. This is not optimal, but the user should not see the difference. Feel free to add more logic here to keep the good elements and only remove the bad ones.
About the GUI freezing, one way to always avoid that is to have the GUI thread separated from other worker threads. The QThread documentation is exhaustive and can help you set up something like this.
At first, the data of the tableview are
apple
pie
banana
After drag and drop(only drag and drop on itself) the item on the tableview, the data of the tableview looks like following
banana
pie
apple
but when I want to iterate the item of the model one by one
codes
for(int i = 0; i != rowCount(); ++i){
if(item(row, Fruit)){
return item(row, Fruit)->data(Qt::DisplayRole).value<QString>();
}
}
it print the data as
apple
pie
banana
expected result
banana
pie
apple
How could I get the “actual” number after drag and drop?
The easiest solution I can think of is create one more column to store the row number of the model, then override the dropEvent, update the row number when the user drop their row.Any easier way to do it?
Edit :
As the example show, the result I want with the codes is "pie, apple, banana".But the actual result is "banana, pie, apple"
The model always operates on the logicalIndex. You need to use the visualIndex of the verticalHeader() for iterating.
for(int i = 0; i < rowCount(); ++i)
{
// i is the logicalIndex
int row = your_table->verticalHeader()->visualIndex(i);
if(item(row, Fruit))
return item(row, Fruit)->data(Qt::DisplayRole).value<QString>();
}
I am working with list control in MFC. I have written code to insert elements into list control present in a dialog box as follows:
int nIndex = 0;
for (int count = 0; count < arrResults.GetSize(); count++)
{
nIndex = m_cListCtrl.InsertItem(count, _T(arrResults[count].ElementAt(0)));
m_cListCtrl.SetItemText(nIndex, 1, _T(arrResults[count].ElementAt(1)));
}
However, when I try to retrieve data from m_cListCtrl, it always returns blank. Also, the GetItemCount() method also returns 0 items. Any suggestions are appreciated.
Following is the data retrieve code that I have written:
arrResults.SetSize(1);
arrResults[0].Add("Header1");
arrResults[0].Add("Header2");
TestDialog testDlg;
testDlg.FillControlList(arrResults); // This function has above code to add data to control list
EXPECT_EQ("Header1", queryDlg.m_cListCtrl.GetItemText(0, 0));
EXPECT_EQ("Header2", queryDlg.m_cListCtrl.GetItemText(0, 1));
The GetItemText function is returning blank string.
When you call FillControlList(), you are using testDlg object. But when you call GetItemText() you're using queryDlg object. You have inserted the items in one dialog and you're trying to get data from different object. Please check with that.
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.
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)