Copy a part of a QTableWidget in an other - c++

I've got a QTableWidget , and I use the method selectedItems() to get all the line selected in my QTableWidget. And now I want to copy all these line in an other QTableWidget, is there a particular function able to do this, or do I need to use a loop ?
If I need to use a loop, can you explain to me how it works ?
Thank You.

With the help of #Kuba Ober, here is my solution :
//Model of my first QTableWidget
QItemSelectionModel *variableModel = ui->variableTableWidget->selectionModel();
//I take the cell selected in my QTableWidget ( I suppose only 1 cell is selected )
QModelIndex item;
QTableWidgetItem* itemCompleteTab = new QTableWidgetItem(); //You can't put a cell to another you have to use a new constructor
foreach (item, variableModel->selectedIndexes()) {
itemCompleteTab->setText(ui->variableTableWidget->item(item.row(),item.column())->text());//Creation of my new cell
ui->visualisationTableWidget->setItem(0,0,itemCompleteTab);//Add in the QTableWidget
}

Related

QTableWidgetItem move cursor to a cell (not select only)

My task is simple. In the table, move to the next row after user writes number and pressed enter key.
I have QTableWidget with key event that is getting cursor position from signal:
connect(ui->table->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), key, SLOT(cell_position(QModelIndex)));
Key event:
...
if ( (key->key()==Qt::Key_Enter) ) {
...
QTableWidgetItem:
...
QTableWidgetItem *item = table->item(m_pos, n_pos);
if(item == nullptr)
{
QTableWidgetItem *item = new QTableWidgetItem;
table->setItem(m_pos, n_pos, item);
item->setSelected(1);
...
But it gives me this behaviour - it selects the cell under currently entered cell. The cursor remains on its position.
Please, do you have any idea how to move cursor down? I tried some QTableWidgetItem methods but did not find any suitable one.
Thanks.
Update:
Instead of
item->setSelected(1);
I use
table->setCurrentItem(item);
which does what I need. It move cursor to the item cell.
If I understand correctly, you want to change the current item, and you can do it calling the QTableWidget::setCurrentItem() method.
See QTableWidget::setCurrentItem

Qt table widget, button to delete row

I have a QTableWidget and for all rows I set a setCellWidget at one column to a button.
I would like to connect this button to a function that delets this row.
I tried this code, which does not work, because if I simply click my button I do not set the current row to the row of the button.
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
QPushButton *b = new QPushButton("delete",this);
ui->tableWidget->setCellWidget(ui->tableWidget->rowCount()-1,0,b);
connect(d,SIGNAL(clicked(bool)),this,SLOT(deleteThisLine()));
...
void MainWindow::deleteThisLine()
{
int row = ui->tableWidget->currentRow();
ui->tableWidget->removeRow(row);
}
How can I connect my button to a function in a way that the function knows which button (at which row) was pressed?
To remove the row we must first get the row, if we are inserting widgets inside the cells the currentRow() method will not return the appropriate row, in many cases it will return the row of the last cell without widget that has been selected.
For that reason you must opt for another solution, for this case we will use the indexAt() method of QTableWidget, but for this we need to know the position in pixels of the cell. when one adds a widget to a cell, this cell will be the parent of the widget, so we can access from the button to the cell using the parent() method, and then get the position of the cell with respect to the QTableWidget and use it in indexAt(). To access the button we will use the sender().
When the current cell is removed the focus is lost, a possible solution is to place the focus again in another cell.
void MainWindow::deleteThisLine()
{
//sender(): QPushButton
QWidget *w = qobject_cast<QWidget *>(sender()->parent());
if(w){
int row = ui->tableWidget->indexAt(w->pos()).row();
ui->tableWidget->removeRow(row);
ui->tableWidget->setCurrentCell(0, 0);
}
}
Use this connection way to connect signal to a slot:
connect(ui->btnDelete, &QPushButton::clicked, this,&MainWindow::deleteRow);
And delete for example a row on call function:
void MainWindow::deleteRow()
{
int row = ui->tableWidget->currentRow();
ui->tableWidget->removeRow(row);
}
Create a custom class, where you pass the created push button object and the row index. From your custom push button class, handle the push button press event and emit a custom signal (it will carry the index number) handled from the object where your custom pushbutton is created. Some related code are below, to give you a hint:
.h
class mypushbutton {
explicit mypushbutton(QObject *parent = 0, QPushButton *pushbutton = 0, int index = 0);
signal:
void deleteRow(int index);
}
.cpp
mypushbutton() {
connect(pushbutton, SIGNAL(clicked(bool)), this, SLOT(actionButtonClick(bool)));
}
actionbuttonclicked() { emit deleteRow(index);}

How to Add processBar inside QTreeWidget cloum

Is there any way in Qt to Add a processBar inside one of QTreeWidget items
Something like this
http://doc.qt.io/qt-5/qtreewidget.html#setItemWidget will do the job for you
just call it for each row with whatever widget you need.
cheers
/edit:
lets say your column 'status' has column index 5, then it would be something like this:
QTreeWidgetItem* item = new QTreeWidgetItem(columnTextsStringList);
/*insert into tree here*/
QProgressBar* progBar = new QProgressBar;
treeWidget->setItemWidget(item, 5/*column of the status*/, progBar);
// no need to delete progBar, its now a child of treeWidget
// use progBar

Hide the checkbox from a QListView item

I wave a QListView that is backed by a QStandardItemModel. Under certain circonstances, the QStandardItem are made checkable. A checkbox gets displayed besides the item's display. At some point, I want to remove hide the QStandardItem checkbox. I set its checkable state to false but it doesn't hide the checkbox (though it cannot be checked anymore).
The only way I have found of hiding the checkbox is to replace the item with a new one. This doesn't seem the proper way to preceed.
This is the code:
MyModel::MyModel(QObject *parent):QStandardItemModel(parent){}
void MyModel::createItem(int row, const QString &text)
{
setItem(row, new QStandardItem(text));
}
void MyModel::setCheckable(int row)
{
item(row)->setCheckState(Qt::Unchecked);
item(row)->setCheckable(true); // A checkbox appears besides the text
}
void MyModel::hideCheckBox(int row)
{
item(row)->setCheckState(Qt::Unchecked);
item(row)->setCheckable(false); // does not work
// I need to completely replace the item for the checkbox to disapear.
// This doesn't seem the proper way to proceed
setItem(row, new QStandardItem(item(row)->data(Qt::DisplayRole).toString()));
}
Is there better way to proceed?
When you call setCheckState or setCheckable, the qt will update the data of list item by adding or setting a Qt::CheckStateRole data. If the Qt::CheckStateRole data is existed, the check icon will be shown. So you need remove it from the data map of the list item.
Finally, the code of hideCheckBox should be:
void MyModel::hideCheckBox(int row)
{
// check the item pointer
QStandardItem* pitem = item(row);
if (pitem == NULL) return;
// find and delete the Qt::CheckStateRole data
QMap<int, QVariant> mdata = itemData(pitem->index());
if (mdata.remove(Qt::CheckStateRole))
{
setItemData(pitem->index(), mdata);
}
}
Hope it useful. :)
I think the presence of the check boxes in items defined by item flags, so that I would write the function in the following way:
void MyModel::hideCheckBox(int row)
{
// Does not set the Qt::ItemIsUserCheckable flag.
item(row)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
}

QStandardItemModel append new items on top of the rest

i like to make my QStandardItemModel that populates items in qtreeview
to append rows on top the allready defined items in the view .
something like the twitter view , new items first.
all i see in the QStandardItemModel is the appendRow/s that appends then to button.
this is what im using now.
SWidget *widget = new SWidget;
QStandardItem *newItem = new QStandardItem;
newItem->setSizeHint( widget->size() );
appendRow( newItem );
view->setIndexWidget( newItem->index(), widget );
void QStandardItemModel::insertRow ( int row, QStandardItem * item ) inserts a row at row containing item. So instead of calling appendRow(newItem); call insertRow(0, newItem);