-1

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

  • I don't really understand what you are looking for... i and j are already the indexes of your rows and columns, what else do you need ? – Jean-Emmanuel Jan 10 '17 at 17:17
  • If you already have the indexes just need to save them on your map as } ***{your map} ["row"] = i; {Your map} ["column"] = j;*** – eyllanesc Jan 10 '17 at 17:35
  • Off topic but... you have a memory leak whereby you allocate a new `QTableWidgetItem` and assign it to `c` but then reassign `c` in the loop without ever deleting the previously allocated memory. – G.M. Jan 10 '17 at 18:02
  • @Jean-Emmanuel What i need now is to try to get just the values of the Rows and The columns,If you notice the MessageBox will show the Rows and The columns, and i want to separate them – user3694419 Jan 10 '17 at 18:48
  • @eyllanesc What i want to store in The Map are the values of the rows and the columns – user3694419 Jan 10 '17 at 18:51
  • @user3694419 When you say the value of the rows and columns, it is a bit confusing. If you are looking for the indexes of those, you already have them. If you need the vector of values of this row, take the index on the row and loop from 0 to range.columnCount(), and push_back those values in a vector. – Jean-Emmanuel Jan 10 '17 at 18:51
  • @Jean-Emmanuel no it's not confusing :), i want the Values ! i have the indexes i'm using them in the two loops, but what i want is the date, the value of for example row[i] and the column[j], so i can store them in a List or a Map – user3694419 Jan 10 '17 at 19:11
  • @Jean-Emmanuel As you can see if i execute this line of code item(i,j)->text() the result will be the values , what the rows and the columns are containting, but the problem here is that the function return them both together, i don't want them togheter i want the rows and the columns separately – user3694419 Jan 10 '17 at 19:12
  • @user3694419 I think that your array has a very special structure that you have not shared with us. Can you share how you construct `range` ? In a regular array, there is no row part or column part of a result. There is the cell, and you can get its value the same way you currently do. A specific example of input / desired output will help us understand. – Jean-Emmanuel Jan 10 '17 at 19:18
  • @Jean-Emmanuel QTableWidgetSelectionRange range = selectedRange(); – user3694419 Jan 10 '17 at 19:20
  • @Jean-Emmanuel Actually my goal here in this code is to have the values of the selected rows and columns so i can use them to generate a QPieChart, – user3694419 Jan 10 '17 at 19:23
  • @user3694419 Please add an example to your post of input / desired output (can be done by hand). – Jean-Emmanuel Jan 10 '17 at 19:25
  • Ok this is a use case : ![link](http://img15.hostingpics.net/pics/996114spreadsheetExample.png), As you can see i have a spreadsheet wich is a QTableWidget so i'm having some values, some data, so i want to have a PieChart using those data, so i select just the data then using those data i can generate the chart – user3694419 Jan 10 '17 at 19:33
  • @Jean-EmmanuelAnd if i execute the code that i gave in the question here is the output :[link]http://img15.hostingpics.net/pics/990523Messages.png The function `c->text()` returs the whole selected values – user3694419 Jan 10 '17 at 19:40
  • Ok I see ! Will your array always be with names in column 1, and data in colum 2 ? Can you have columns 3,4,...? What behavior would you like in this case, a sum on the row ? or each cell independently ? It looks like you need to always ignore the column 1 (where you have the names) in the function above, and only read it when you need to label your data. – Jean-Emmanuel Jan 10 '17 at 19:43
  • @Jean-Emmanueloh duude i didn't understand what you mean :D – user3694419 Jan 10 '17 at 19:49

1 Answers1

2

Here is what I understood from the comments, feel free to correct me and I'll update my answer if necessary.

enter image description here

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);
Jean-Emmanuel
  • 688
  • 8
  • 18
  • Thats it exactly because i want to use the [Gas,22] as Abscissa and ordinate for my PieChart – user3694419 Jan 10 '17 at 20:15
  • But i don't understand why you put a 0 in the columns attribut of `item(i,0)->text()` – user3694419 Jan 10 '17 at 20:16
  • So now i can use the QMap to draw my PieChart, Actually i'm gonna use the example giving the QT Documentation [link]http://doc.qt.io/qt-5/qtcharts-piechart-example.html – user3694419 Jan 10 '17 at 20:19
  • @user3694419 `item(i,0)->text()` is because the column 0 always contains the name of your data. It's a string and not an int. Let me know if that works. – Jean-Emmanuel Jan 10 '17 at 20:32
  • Actually it's kind hard for me to prove if it's working correctly (your code snippet is working i can show the data and values separately and thank you) what i want now is when i click on a button a new DialogBox will show the new QPie using the details of the myMap variable – user3694419 Jan 10 '17 at 20:45
  • for now i created a simple dialogbox using the qt designer that generate me a cpp and a header files, – user3694419 Jan 10 '17 at 20:50
  • @user3694419 I updated my answer to explain how to use the QMap to fill the QPieSeries – Jean-Emmanuel Jan 10 '17 at 21:16
  • Thank you so much i appreciate that , but i have another question, how i can show the chart in a new QDialogBox ? cuz when i wrote this `ChartDialog chart=new ChartDialog();` and then execute the show() function nothing happens – user3694419 Jan 10 '17 at 21:26
  • @user3694419 I'm not sure you can add a widget to a QDialog. You should create a separate window and follow the tutorial. – Jean-Emmanuel Jan 10 '17 at 21:28
  • I create a Dialog using the Qt Designer and i want to show the result in this Dialog when i click on a QAction event that's in a nother QMainWindow class – user3694419 Jan 10 '17 at 21:30
  • @user3694419 I believe you cannot add a widget to a QDialog. QPieChart will not be shown inside of it. Use a different class. – Jean-Emmanuel Jan 10 '17 at 21:32
  • I'm having errors on `QMap::iterator` so replace them with `QMap` but another problem shows in the loop `for(; it::iterator' and 'QMap::iterator') for(; it – user3694419 Jan 10 '17 at 21:36
  • @user3694419 my bad, went to fast on this one. You are right on the change of QMap, and you need to change the `it – Jean-Emmanuel Jan 10 '17 at 21:38
  • Thank you :) And another error yaay -_- it's in `series->append(it->first, it->second);` **request for member 'first' in '* it.QMap::iterator::operator->()', which is of non-class type 'int' series->append(it->first, it->second);** – user3694419 Jan 10 '17 at 21:42
  • Is it problem of type maybe we need a cast, maybe i used the int as a value but the append method in QPieSeries accept a **qreal** type ? – user3694419 Jan 10 '17 at 21:43
  • @user3694419 No I think std::map uses first and second, where as QMap uses `it->key()` and `it->value()`. I updated the code. – Jean-Emmanuel Jan 10 '17 at 21:45
  • Still the same error **request for member 'key' in '* it.QMap::iterator::operator->()', which is of non-class type 'int' series->append(it->key(), it->value());** **request for member 'value' in '* it.QMap::iterator::operator->()', which is of non-class type 'int' series->append(it->key(), it->value());** – user3694419 Jan 10 '17 at 21:49
  • The int type does not work with QPie, so we need to change this to either qreal or double (qreal is just a `typedef` or double). – Jean-Emmanuel Jan 10 '17 at 21:54
  • And if we use this loop ?`for(QString e : myMap.keys()){ series->append(e,myMap.value(e)); }` – user3694419 Jan 10 '17 at 21:55
  • @user3694419 Probably works too yes ! If you have c++11 – Jean-Emmanuel Jan 10 '17 at 21:56
  • I changed the qmap from `QMap` to `QMap` but still the same problem – user3694419 Jan 10 '17 at 21:58
  • i'm using the QT 5.7 version – user3694419 Jan 10 '17 at 21:58
  • Then you can try qreal. I can't help you much on that, I have never created QPieChart. You can create a new question if you need specific answers. – Jean-Emmanuel Jan 10 '17 at 22:02
  • i used the foreach loop and changed the int to double and everything is ok now what i need to do is try to show the Chart in a new MainWindow, actually the MainWindow will be shown when i'll click on a QAction after selecting the rows and columns of course – user3694419 Jan 10 '17 at 22:05
  • In my project i have two classes, one is a MainWindow, and the second is a class that inherits from QTableWidget when i did all this code of getting values from selected range, and what i want to do now is when i click on a QAction in the MainWindow class, i'll call the method of drawing the QPie Chart and show the chart in a new Window(Dialog or QMainWindow) – user3694419 Jan 10 '17 at 22:10
  • Please ask a second specific question on SO. Otherwise, the work here will not be accessible to other persons having the same issue as you. – Jean-Emmanuel Jan 10 '17 at 22:15
  • Thank you so much for your help i really appreciate your support and answers :) – user3694419 Jan 10 '17 at 22:16