Modify all selected cells in a QTableWidget? - qt

It is a standard QTableWidget
All cells are QTableWidgetItem.
All cells are editable/selectable
Question: How can I modify all the cells I have selected?

Possible way is to use the dialog open. So the idea is like this :
Select the items
Make a button or something to open input dialog.
Apply the value of input dialog to all selected items.

I was facing a similar problem a couple years ago and I solved it like this:
I have inherited my own view and I have reimplemented methods commitData() and mouseReleaseEvent().
commitData takes all selected indices from the selection model and calls QAbstractItemModel::setData() for all of them. Data are taken from the editor like this:
QByteArray n = editor->metaObject()->userProperty().name();
if (n.isEmpty())
n = delegate->itemEditorFactory()->valuePropertyName(model()->data(index, Qt::EditRole).userType());
if (!n.isEmpty())
{
QVariant data = editor->property(n);
for (const QModelIndex & idx : selectedIndices)
{
model()->setData(idx, data);
}
}
mouseReleaseEvent() performs three steps:
Get a current selection from the selection model.
Call original event handler (QTableWidget::mouseReleaseEvent())
Restore selection: QItemSelectionModel::select()

Related

how to add QSpinBox to a QTableWidget?

I have a QTableWidget and an object of class product called p.
I wanna add items to this table.
I tried the code below but no use.
void MainWindow:: add_to_basket (product p){
ui->tableWidget->insertRow(1);
QLineEdit *qle=new QLineEdit();
qle->setText(p.get_name());
ui->tableWidget->setCellWidget(1,1,qle);
QLineEdit *qle1=new QLineEdit();
qle1->setText(QString::number(p.get_price()));
ui->tableWidget->setCellWidget(1,2,qle1);
QSpinBox *qsb=new QSpinBox();
qsb->setValue(p.get_count());
ui->tableWidget->setCellWidget(1,3,qsb);
}
what should I do?
QTableWidget should have defined rowCount and columnCount properties. It can be done either via QTableWidget constructor (https://doc.qt.io/qt-5/qtablewidget.html#QTableWidget-1) or via appropriate methods (setRowCounts and setColumnCounts). If it is done already, that's great.
insertRow inserts an empty row into the table at given position. ui->tableWidget->insertRow(1) would insert a new row at position 1 only if you have previously defined rowCount and columnCount (see point 1).
It depends what is your idea here - if you would like to have at least 4 columns (please note that we are counting from 0 and the QSpinBox is attempted to be put into third column) and insert new product always at first row, your code with point 1 fullfilled will be work fine. But, if your idea is to add a new row each time new product is added, you should rather call ui->tableWidget->insertRow(tableWidget->rowCount()) and use that value to address appropriate row.
You may also want to have a look here for example how to setup QTableWidget: https://wiki.qt.io/How_to_Use_QTableWidget

Hidden sort indicator on column in QTreeView

I have QTreeView and I setSortEnable = true for it, and all of column show sort indicator, but now I want last column do not show sort indicator, just last column.
Have any idea or solution for my issue..:(
please help
Thanks
QHeaderView always draws the sorting indicator on a column when data is sorted by this column (if setSortIndicatorShown is true).
That is why it look like the only way to prohibit drawing of the indicator is to prohibit sorting of the column by left-click.
To prohibit sorting by a certain column you need:
1. create a new class inherited from QHeaderView (or use an event filter)
2. reimplement mouseReleaseEvent and mousePressEvent
3. use logicalIndexAt to indicate that user clicked on the column
4. call setSectionsClickable(false) before calling the base method and setSectionsClickable(true) after it.
Example:
void HeaderView::mouseReleaseEvent(QMouseEvent* e)
{
const int index = logicalIndexAt(e->pos());
if (index == 3) setSectionsClickable(false);
QHeaderView::mouseReleaseEvent(e);
setSectionsClickable(true);
}
Do the same for mousePressEvent.
thus you will prohibit sorting of a certain column
In my case, I've three columns and it was necessary to hide the sort indicator of the second column.
Because of I had custom rules of sorting, just got QHeaderView::sectionClicked event with OnHeaderClicked(int column) slot, and did this:
switch (column)
{
case 0:
// Custom sorting operations
break;
case 1:
tree_widget_->sortByColumn(-1);
break;
case 2:
// Custom sorting operations
break;
}

Flex mobile - How do I move to the next data in List.selectedItem when moving to next page?

When I move page01 to page02, I pass the same data along with it using the following code:
navigator.pushView(Page02, data);
How do I move to page02 with passing the next row of data (instead of the same data)?
In other word, how to increment to the next row of data with pushView?
Thanks.
If you have access to the List component which displays the data you want to pass into views, you can do something like this:
myList.dataProvider[myList.selectedIndex+1]
You'll want to do some checking to make sure that you're trying to reference an index that actually exists:
var mySelectedObject :Object;
if(myList.selectedIndex+1 < myList.dataProvider.length){
mySelectedObject = myList.dataProvider[myList.selectedIndex+1]
} else {
// do some other behaviour; such as selecting the first one in the list
mySelectedObject = myList.dataProvider[0]
}
navigator.pushView(page02, mySelectedObject );

(Py)Qt - QTreeView, Model, insert row

I am little bit confuse.
I am working with QTreeView as model I assigned QSortFilterProxyModel.
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qsortfilterproxymodel.html
//treeview
self.ProxyView = QtGui.QTreeView(self.centralwidget)
//model
self.ProxyModel = QtGui.QSortFilterProxyModel(self)
self.ProxyModel.setSourceModel(QtGui.QStandardItemModel(0, 3, self))
//assign model to tree
self.ProxyView.setModel(self.ProxyModel)
On button click I want to add row to this tree.
Here is my slot
def pushButton_addRow(self):
self.ProxyModel.insertRow(0)
self.ProxyModel.setData(self.ProxyModel.index(0,0), "hi")
It doesnt work, it works only for first row, then I added empty rows. But wenn I fill second cell it works.
self.ProxyModel.setData(self.ProxyModel.index(0,1), "hi")
Any Idea?
Maybe your new QModelIndex has wrong parent()?

Flex - sorting a datagrid column by the row's label

I'm creating a table that displays information from a MySQL database, I'm using foreignkeys all over the place to cross-reference data.
Basically I have a datagrid with a column named 'system.' The system is an int that represents the id of an object in another table. I've used lableFunction to cross-reference the two and rename the column. But now sorting doesn't work, I understand that you have to create a custom sorting function. I have tried cross-referencing the two tables again, but that takes ~30sec to sort 1200 rows. Now I'm just clueless as to what I should try next.
Is there any way to access the columns field label inside the sort function?
public function order(a:Object,b:Object):int
{
var v1:String = a.sys;
var v2:String = b.sys;
if ( v1 < v2 ){
trace(-1);
return -1;
}else if ( v1 > v2 ){
trace(1);
return 1;
}else {
trace(0);
return 0;
}
}
One way to handle this is to go through the objects you received and add the label as a property on each of them based on the cross-referenced id. Then you can specify your label property to display in your data grid column instead of using a label function. That way you would get sorting as you'd expect rather than having to create your own sort function.
The way that DataGrids, and other list based classes work is by using itemRenderers. Renderers are only created for the data that is shown on screen. In most cases there is a lot more data in your dataProvider than what is seen on screen.
Trying to sort your data based on something displayed by the dataGrid will most likely not give you the results you want.
But, there is no reason you can't call the same label function on your data objects in the sortFunction.
One way is to use the itemToLabel function of the dataGrid:
var v1:String = dataGrid.itemToLabel(a);
var v2:String = dataGrid.itemToLabel(b);
A second way is to just call the labelFunction explicitly:
var v1:String = labelFunction(a);
var v2:String = = labelFunction(b);
In my experience I have found sorting to be extremely quick, however you're recordset is slightly larger than what I usually load in memory at a single time.

Resources