QSqlTableModel - filter not working? - qt

I created a QSqlTableModel, set a filter and used a QTableView to show a table of my filtered data. This works as expected...
model = new QSqlTableModel;
model->setTable("XXX");
model->select();
model->setFilter(filter);
table = new QTableView;
table->setModel(model);
However, when I try to compute the sum of all visible values of a column in the table view...
float sum = 0.0f;
for(int i=0;i<model->rowCount();i++)
sum += model->record(i).value("amount").toFloat();
... I get the sum of ALL entries in the table model, NOT only of those items visible in the TableView (where the filter is applied).
How can I make my sum()-function to compute the sum of only those values which are visible in the TableView?
Thank you for your answers!

model = new QSqlTableModel;
model->setTable("XXX");
model->setFilter(filter);
*model->select();//select after set filter*
table = new QTableView;
table->setModel(model);

Related

How to add after selected row in tableview?

I have selected row, and I need to add some data right below it. Row is selected with OrderTable selectedOrderTable = orderTableId.getSelectionModel().getSelectedItem(); and new one is added with data.add(new OrderTable( ... )) It's adding OK to table, just at bottom of it, and I need to add it right below selected row selectedOrderTable.
Just call the add method taking an index:
int index = orderTableId.getSelectionModel().getSelectedIndex();
data.add(index + 1, new OrderTable(...));

Xamarin grid, column and row amounts

Hi im relatively new to c# code and i was wondering if there is any way to get the amount of columns and rows in a grid and store that amount in a variable
Something like:
var columnamount = grid.columnamount;
But i could not find anything that works
Thanks
You can use the following code to get a count of the columns and rows directly via the ColumnDefinitions and RowDefinitions properties. No need to enumerate the children of the grid because you may not have views in every column/row.
var columnCount = grid.ColumnDefintions.Count;
var rowCount = grid.RowDefinitions.Count;
For reference the documentation.
You might be able to do it this way, purely based on what I see in the docs:
var countColumns = grid.Children.Where( c => c.Column).Max();
var countRows = grid.Children.Where( c => c.Row).Max();
But I'm not sure if you can access Row anf Column properties on the child element.
This is not the best way to check, I guess, but it's working (same thing for columns):
EDIT: nope, for columns it doesn't work
int GetRowsCount(Grid grid)
{
var item = grid.Children.FirstOrDefault();
return item != null ? Grid.GetRow(item) + 1 : 0;
}

Get The Row,Column values from a cell in QT

I have a problem, i want to return the selected Rows values, and the columns separately, i found a method to return both of them using the function cell(row, column), but i want to get them separately
Here is my code :
QTableWidgetItem *c = new QTableWidgetItem();
QMap<QString,int> lists;
for(i=0;i<range.rowCount();++i){
for(int j=0;j<range.columnCount();++j){
c=item(i,j);// here i can return the Rows, Columns Data
QMessageBox::information(this,"",c->text());
}
}
As you can see this code is working, but i just want to return the Rows and the Columns separately so i can put them in my QMap<QString,int> list.
And the purpose of all this is to try to draw a piechart from the selected rows and columns
So Any help please
Here is what I understood from the comments, feel free to correct me and I'll update my answer if necessary.
COL1 | COL2
NAME | VALUE
So when you select a cell, you actually care about the whole row, a.k.a the name of the row and the value associated. If this is the case, it would make more sense to only allow the user to select whole rows, instead of cells. setSelectionBehavior(QAbstractItemView::SelectRows); should do the trick.
Provided that the name of the dataset is always in column 1, and the value in column 2, you should update your code with the snippet:
QTableWidgetItem *c; //Deleted memory leak in your code.
QMap<QString,double> myMap; //Don't name it a list if it is explicitly a map.
for(i=0;i<range.rowCount();++i){
QString dataName = item(i,0)->text();
int dataValue;
for(int j=1;j<range.columnCount();++j){
c=item(i,j);// here i can return the Rows, Columns Data
dataValue += c->text().toDouble();
//If you always have 2 columns only, dataValue will be the value you are looking for.
//If you can have more than 2 columns, dataValue will be the sum of all the cells located after the column 0, on the same row.
//Change this depending on how you want to treat those values.
QMessageBox::information(this,dataName,c->text());
}
myMap[dataName]=dataValue;
}
EDIT for QPieSeries, following this example:
QPieSeries *series = new QPieSeries();
QMap<QString,double>::iterator it = myMap.begin();
QMap<QString,double>::iterator end = myMap.end();
for(; it!=end; ++it){
series->append(it->key(), it->value());
}
QPieSlice *slice = series->slices().at(1);
slice->setExploded();
slice->setLabelVisible();
slice->setPen(QPen(Qt::darkGreen, 2));
slice->setBrush(Qt::green);
QChart *chart = new QChart();
chart->addSeries(series);
chart->setTitle("My Data");
chart->legend()->hide();
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
/*change with your window here*/
yourWindow.setCentralWidget(chartView);

QTableWidget cast loses selectedItems

I am adding QTableWidgets to a layout (called tableArea). I have a function that I want to be able to go through all the selected items in all tables I have added to my layout:
for (int i=0; i <ui->tableArea->count(); i++)
{
QTableWidget *tableI = (QTableWidget*)ui->tableArea->itemAt(i)->widget();
int rowCount = tableI->rowCount(); // just to test if correct info
QList<QTableWidgetItem*> list = tableI->selectedItems(); // This is empty!!
}
The function iterates through correct tables, and it even knows the right row count for each table, but it doesn't seem to know which items are selected in the table. When I select items, this function doesn't seem to recognize that there is something selected. I imagine this has to do with the cast. Any idea? Thanks in advance!

Is swapping the columns and rows of a flex datagrid possible?

I have a 1 row, many column flex datagrid. I would like to turn the dataGrid on its side, so that the column headers become a single column running down and v.v.
Is there a way to do that in the DataGrid?
Or am I stuck manipulating the data presented to the grid? If so whats your recommendation?
The main idea here is I have an object like:
x=y
b=u
o=p
u=e
w=p
And I'd like a control that is visually similar to that. Currently the datagrid displays the object as:
x b o u w
y u p e p
Which is too horizontal for my case. Thx
I presume that you want to convert your columns in to a single column
this can be done by getting all the columns and put the in array as provide it as a dataprovider.
DataGrid.columns
will return the columns.
and you can do some think like this to create columns.
public function createColumns():Array{
var advancedDataGridColumn:AdvancedDataGridColumn;
var i:int;
var columnsArray:Array = new Array();
for(i=0;i<columns.length;i++){
advancedDataGridColumn=new AdvancedDataGridColumn();
advancedDataGridColumn.headerText=columns[i].dispheader.toString();
advancedDataGridColumn.dataField="#"+columns[i].name.toString();
advancedDataGridColumn.itemRenderer=new ClassFactory(Styler);
if(columns[i].descending!=undefined ){
if(columns[i].descending.toString()=="true")
sortField = new SortField("#"+columns[i].name.toString(),false,true,null);
else
sortField = new SortField("#"+columns[i].name.toString(),false,false,null);
}
if(advancedDataGridColumn.headerText == Constants.price||
advancedDataGridColumn.headerText == Constants.quantity||
advancedDataGridColumn.headerText == Constants.askPrice||
advancedDataGridColumn.headerText == Constants.bidPrice||
advancedDataGridColumn.headerText == Constants.netAmount||
advancedDataGridColumn.headerText == Constants.interestAmount||
advancedDataGridColumn.headerText == Constants.principalAmount||
advancedDataGridColumn.headerText == Constants.accruedInterestAmount){
var currencyFormattor:CurrencyFormatter = new CurrencyFormatter();
currencyFormattor.useThousandsSeparator=true;
currencyFormattor.currencySymbol="";
currencyFormattor.thousandsSeparatorFrom=",";
currencyFormattor.thousandsSeparatorTo=",";
advancedDataGridColumn.formatter=currencyFormattor;
}
columnsArray.push(advancedDataGridColumn);
}
return columnsArray;
}
sorry i just copied the code but i think it will help you.
Set the DataGrid to have only 2 columns and transform the original dataset to an array collection of {propName, propValue}.
Say you have:
var originalDataSet : ArrayCollection;
var dataSet : ArrayCollection;
var columnSet : ArrayCollection;
Once you have the original values, you'll do something like:
dataSet = new ArrayCollection();
for (var i : int; i < originalDataSet.length; i++)
{
dataSet.addItem({name : columnSet.getItemAt(i), value : originalDataSet.getItemAt(i)});
}
myDataGrid.dataProvider = dataSet;//set the data provider of the grid to the transformed data set.
To clarify:
{name : columnSet.getItemAt(i), value : originalDataSet.getItemAt(i)}
This creates a new instance of type Object and assigns the name and value dynamic properties to their respective values. Instead of this you might want to define your own class with bindable properties. Note that the property names are just for this example because I don't know what you're working with actually.
The data grid at that point should have two columns defined by you, with their dataField properties set accordingly. Also, this example assumes columnSet collection contains the "horizontal columns" that you want displayed vertically. If you can obtain these based on the values in the originalDataset, you might not even need columnSet.

Resources