Qcombobox remove and add item in C++ Qt - c++

Creating a combobox in Qtableview2 column 1 and passing values from Qtableview1 column1
so i am storing column1 table1 values in Qstringlist and passing to combobox
void cymodel::rowvalues() {
QAbstractItemModel* table1 = ui.tableView->model();
QAbstractItemModel* table2 = ui.tableView_2->model();
QStringList colvallist1;
for (int r = 0, maxI = table1->rowCount(); r < maxI; ++r)
colvallist1.append(table1->data(table1->index(r, 0)).toString());//store value in stringlist
for (int i = 0, maxI = table2->rowCount(); i < maxI; ++i)//for all rows
{
const QModelIndex idx = table2->index(i, 1);
QComboBox* combo = qobject_cast<QComboBox*>(ui.tableView_2->indexWidget(idx));
if (!combo)
{
combo = new QComboBox(); // make combo
ui.tableView_2->setIndexWidget(idx, combo);// add combo
}
// combo->model()->removeRows(0, combo->count(), combo->rootModelIndex());
colvallist1.removeDuplicates(); // clear duplicates in colvallist1
colvallist1.removeAll(QString("")); //remove empty row data
combo->setPlaceholderText(QString(" "));
combo->addItems(colvallist1);
}
}
connect(ui.tableView->model(), &QAbstractItemModel::dataChanged, this,
&cymodel::rowvalues);
Using removerows() all items are removed everytime,,if I added some values in column0 table1 then select in combobox and again adding values in table1 Column0 that time combobox selection go away
but if i don't use removerows() then when I'm adding new item to combobox then its adding multiple time like 2 values added then i add 2 more in table1 col then in combobox it become 4
So, how to add those that appear in colvallist1 but are not already in the combo & remove those that don't appear in colvallist1 ??
Thanks Plz help!!

thnks,,,i solved this..
to remove the items in combobox which are not in colvallist1..without change in selection
here is the code--
void cymodel::rowvalues() {
QAbstractItemModel* table1 = ui.tableView->model();
QAbstractItemModel* table2 = ui.tableView_2->model();
QStringList colvallist1;
for (int r = 0, maxI = table1->rowCount(); r < maxI; ++r)
colvallist1.append(table1->data(table1->index(r, 0)).toString());//store value in stringlist
for (int i = 0, maxI = table2->rowCount(); i < maxI; ++i)//for all rows
{
const QModelIndex idx = table2->index(i, 1);
QComboBox* combo1 = qobject_cast<QComboBox*>(ui.tableView_2-
>indexWidget(idx));
if (!combo1)
{
combo1 = new QComboBox(); // make combo
ui.tableView_2->setIndexWidget(idx, combo);// add combo
}
colvallist1.removeDuplicates(); // clear duplicates in colvallist1
colvallist1.removeAll(QString("")); //remove empty row data
combo1->setPlaceholderText(QString(" "))
QString selected = combo1->currentText();
int indx = combo1->currentIndex();
combo1->clear();
combo1->addItems(colvallist1);
combo1->findData(selected);
combo1->setCurrentIndex(indx);
combo1->setCurrentText(selected);
}

Related

Use QAxObject to save the data of QTableView as local excel sheets

I need a feature to save the data of qtableview as local excel sheet,i can get data from qtableview,i can make sure that values have been token correctly from qtableview when i step into my 'SetCellValue' function,but they are incorrect in my excel sheet
Get value from qtableview and set them into my excel sheet
for (int row = 0; row < m_nDefectNum[2]; row++)
{
QModelIndex NoModelIndex = categoriesTableList[2]->model()->index(row, 0);
QModelIndex NameModelIndex = categoriesTableList[2]->model()->index(row, 1);
QModelIndex backACountModelIndex = categoriesTableList[2]->model()->index(row, 2);
QModelIndex backARateModelIndex = categoriesTableList[2]->model()->index(row, 3);
QModelIndex backBCountModelIndex = categoriesTableList[3]->model()->index(row, 2);
QModelIndex backBRateModelIndex = categoriesTableList[3]->model()->index(row, 3);
QString backCountStr = QString::number(categoriesTableList[2]->model()->data(backACountModelIndex).toInt() + categoriesTableList[3]->model()->data(backBCountModelIndex).toInt());
QString backRateStr = QString::number(categoriesTableList[2]->model()->data(backARateModelIndex).toDouble() + categoriesTableList[3]->model()->data(backBRateModelIndex).toDouble(), 'f', 2) + "%";
excel->SetCellValue(row + 1, 0, categoriesTableList[2]->model()->data(NoModelIndex).toString());
excel->SetCellValue(row + 1, 1, categoriesTableList[2]->model()->data(NameModelIndex).toString());
excel->SetCellValue(row + 1, 2, backCountStr);
excel->SetCellValue(row + 1, 3, backRateStr);
}
SetCellValue
void ExcelExporterHelper::SetCellValue(int row, int column, const QString& value)
{
int cellRow = row + 1;
int cellCol = column + 1;
QAxObject* pRange = m_pSheet->querySubObject("Cells(int,int)", cellRow, cellCol);
pRange->dynamicCall("SetValue(const QString&)",value);
}
such as , the value i get are "300 30%",they will become "300 300%" when i see the excel file,i don't know what's wrong with my code, i need some help,
i can sure that values have been token from qtableview successfully,but failed when they are saved into excel
step into
my excel

Impossible to delete the last column in a ListView?

I am having a bit of a trouble here. It seems I can't remove all the columns or (reset) a listview. Here is the relevant code:
HWND resultListView = GetDlgItem(hwnd, IDC_RESULTCONTROL);
SendMessage(resultListView, LVM_DELETEALLITEMS, 0, 0); //All items are deleted
//Get numebr of columns
HWND hWndHdr = (HWND)::SendMessage(resultListView, LVM_GETHEADER, 0, 0);
int count = (int)::SendMessage(hWndHdr, HDM_GETITEMCOUNT, 0, 0L);
for (int colIndex = 0; colIndex < count; colIndex++) {
ListView_DeleteColumn(resultListView, colIndex);
}
///... Irrelevant code
HWND listbox = GetDlgItem(hwnd, IDC_SELECTEDLISTBOX);
int numberOfItemsSelected = SendMessage(listbox, LB_GETLISTBOXINFO, 0, 0);
vector<string> selectedItemsStringsVector;
char buf[250];
LVCOLUMN buffer;
//Add Selected Columns
for (int i = 0; i < numberOfItemsSelected; i++) { //In this case always 2 "Date" and "Time" for testing.
SendMessage(listbox, LB_GETTEXT, i, (LPARAM)buf);
selectedItemsStringsVector.push_back(buf);
buffer.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
buffer.fmt = LVCFMT_LEFT;
buffer.cx = 100;
buffer.pszText = buf;
buffer.cchTextMax = lstrlen(buf);
buffer.iSubItem = i;
buffer.iImage = 0;
buffer.iOrder = 0;
ListView_InsertColumn(resultListView, i, &buffer); //Works fine. Maybe I add an extra column here??
}
In debug mode, all my variables have the expected values.
FirstButtonClick column count in debug mode (variable count = 2) all good.
SecondButtonClick Column count = 3. But it does not delete them?
English is not my main language and I am kind of stumped right now...
The indices of columns in a header control are always consecutively numbered, starting at 0. User code does not control the index of a column. When deleting a column, the indices of columns towards higher indices are shifted down by 1. This is the reason, why the call to ListView_DeleteColumn eventually fails.
There are two options to solve this:
Delete columns starting at the final index down to 0. Deleting the last column does not change the index of other columns, so they stable throughout the deletion operation.
Always delete the first column (at index 0).
The second option is both easier to implement as well as read. The following loop will delete all columns:
for (int colIndex = 0; colIndex < count; ++colIndex) {
ListView_DeleteColumn(resultListView, 0);
}

QT QTableWidget::item() returns nullptr even when widget assigned to it

This is driving me nuts. Here's the relevant code:
//Inside UI class
QTableWidget *table_view;
Later,
QLabel* lb_param_id = new QLabel(this);
lb_param_id->setText(QString::number(param_id));
QLabel* lb_param_name = new QLabel(this);
lb_param_name->setText(QString(param_name));
QLineEdit* te_value = new QLineEdit(this);
te_value->setText(QString(value));
QPushButton* pb_command = new QPushButton();
pb_command->setText("Change");
...
if(ui->table_view->rowCount() <= param_id)
ui->table_view->setRowCount(param_id + 1);
ui->table_view->setCellWidget(param_id, 0, lb_param_id);
ui->table_view->setCellWidget(param_id, 1, lb_param_name);
ui->table_view->setCellWidget(param_id, 2, te_value);
ui->table_view->setCellWidget(param_id, 3, pb_command);
for(int i =0; i < ui->table_view->rowCount(); ++i)
{
for(int j = 0; j < ui->table_view->columnCount(); ++j)
{
QTableWidgetItem* item = ui->table_view->item(i, j);
//Here, item is nullptr. Why?
item->setForeground(QColor::fromRgb(255,255,255));
}
}
I set widgets, then try to change foreground of all widgets inside QTableWidget. However, what is returned from ui->table_view->item() is nullptr. What is going on here? btw, The column count is set at initialization.
Add following few lines of code.
if(ui->table_view->rowCount() <= param_id)
ui->table_view->setRowCount(param_id + 1);
ui->table_view->setColumnCount(4);
ui->table_view->setItem(param_id, 0, new QTableWidgetItem());
ui->table_view->setItem(param_id, 1, new QTableWidgetItem());
ui->table_view->setItem(param_id, 2, new QTableWidgetItem());
ui->table_view->setItem(param_id, 3, new QTableWidgetItem());
ui->table_view->setCellWidget(param_id, 0, lb_param_id);
...
Basically, you need to insert the data into the cell first before you can set widget. In your case, you don't have meaning fully data.
Inspecting the qt source, this is the how setCellWidget() imaplemented:
void QTableWidget::setCellWidget(int row, int column, QWidget *widget)
{
QModelIndex index = model()->index(row, column, QModelIndex());
QAbstractItemView::setIndexWidget(index, widget);
}
Without setting the cell first, the model index is invalid index. I agree qt should insert the data if returned index is invalid. For now, you have to work with qt code.

QTableView resize vertically data not refreshed

I've implemented a table through deriving QTableView and QAbstractTableModel. It all seems to work fine except when I resize the table vertically the rows that were originally out of view don't show any data.
There is no issue when resizing horizontally possibly because I've overridden the resizeEvent() method and am recalculating column widths which I obviously don't do if the table is resized vertically.
I'm using the following code in the model to add data to the table:
bool DDUTableModel::insertRow(int row, const QModelIndex& parent)
{
beginInsertRows(parent, row, row);
digital_display_list_.append(DigitalDisplayData(path_));
endInsertRows();
return true;
}
The resizeEvent() looks like this:
void DDUTableView::resizeEvent(QResizeEvent* ev)
{
int num_columns = NUM_ELEMENTS(COLUMN_WIDTHS);
if (num_columns > 0) {
int width = ev->size().width();
int used_width = 0;
// Set our widths to be a percentage of the available width
for (int i = 0; i < num_columns - 1; i++) {
int column_width = (width * COLUMN_WIDTHS[i]) / 100;
this->setColumnWidth(i, column_width);
used_width += column_width;
}
// Set our last column to the remaining width
this->setColumnWidth(num_columns - 1, width - used_width);
}
}
Any ideas?
The problem was with the resizeEvent(). I need to also invoke the method in the QTableView class that I derived from to force a refresh on vertical resizing. Amended method looks like this:
void DDUTableView::resizeEvent(QResizeEvent* ev)
{
int num_columns = NUM_ELEMENTS(COLUMN_WIDTHS);
if (num_columns > 0) {
int width = ev->size().width();
int used_width = 0;
// Set our widths to be a percentage of the available width
for (int i = 0; i < num_columns - 1; i++) {
int column_width = (width * COLUMN_WIDTHS[i]) / 100;
this->setColumnWidth(i, column_width);
used_width += column_width;
}
// Set our last column to the remaining width
this->setColumnWidth(num_columns - 1, width - used_width);
}
QTableView::resizeEvent(ev);
}

How to select next row in QTableView programmatically

I have QTableView subclass that I am marking and saving its state with this :
connect(this,
SIGNAL(clicked(const QModelIndex &)),
this,
SLOT(clickedRowHandler(const QModelIndex &))
);
void PlayListPlayerView::clickedRowHandler(const QModelIndex & index)
{
int iSelectedRow = index.row();
QString link = index.model()->index(index.row(),0, index.parent()).data(Qt::UserRole).toString();
emit UpdateApp(1,link );
}
now i like programmatically to move the selection to the next row (not by pressing the row with the mouse)
and invoking clickedRowHandler(...) how shall i do that ?
Thanks
You already have the current row index, so use something like the following to get the modelindex for the next row
QModelIndex next_index = table->model()->index(row + 1, 0);
Then you can set that modelindex as the current one using
table->setCurrentIndex(next_index);
Obviously you'll need to make sure you're not running past the end of the table, and there's probably some extra steps to make sure the entire row is selected, but that should get you closer.
/*
* selectNextRow() requires a row based selection model.
* selectionMode = SingleSelection
* selectionBehavior = SelectRows
*/
void MainWindow::selectNextRow( QTableView *view )
{
QItemSelectionModel *selectionModel = view->selectionModel();
int row = -1;
if ( selectionModel->hasSelection() )
row = selectionModel->selection().first().indexes().first().row();
int rowcount = view->model()->rowCount();
row = (row + 1 ) % rowcount;
QModelIndex newIndex = view->model()->index(row, 0);
selectionModel->select( newIndex, QItemSelectionModel::ClearAndSelect );
}