PDA

View Full Version : Write new data into QTableWidgetItem, convert float into QTableWidgetItem



Blitzor DDD
17th July 2016, 10:26
Hello!

this is the code, I wrote:


#include "widget.h"

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->setGeometry(30,30,800,750);
rank = new QLineEdit("Enter the Rank", this);//rank->setGeometry(10,0,20,20);
ok = new QPushButton("Ok", this); ok->setGeometry(150, 0,80,30);
calculate = new QPushButton("calculate",this); calculate->setGeometry(250,0,80,30);

coppy = new QTableWidgetItem;

connect(ok,SIGNAL(clicked()),this,SLOT(ok_clicked( )));
connect(calculate,SIGNAL(clicked()),this,SLOT(calc ulate_clicked()));
}

Widget::~Widget()
{

}

void Widget::ok_clicked()
{

rank_of_Matrix = rank->text().toDouble();
tbl=new QTableWidget(rank_of_Matrix,rank_of_Matrix,this);
tbl->setGeometry(20,50,770,250);
tbl->show();

tbl->setItem(2,2,ptwi = new QTableWidgetItem(QString::number(40)));


Action_toArray(); // wrote all information into Array A[i][j] and make 0 all elements equals to zero

}

void Widget::calculate_clicked()
{
tbl = new QTableWidget(rank_of_Matrix,rank_of_Matrix,this);

tbl ->setGeometry(20,350,770,250);
tbl->setItem(2,2, coppy->clone());
tbl ->show();
}

void Widget::Action_toArray()
{

A= new float* [rank_of_Matrix];
for(int i=0;i<rank_of_Matrix;i++){
A[i]=new float [rank_of_Matrix];
}

for(int i=0;i<rank_of_Matrix;i++){
for(int j=0;j<rank_of_Matrix;j++){
//wrote into Array from QTableWidget
A[i][j] = tbl->item(i,j)->data(Qt::DisplayRole).toFloat();
}
}

//make all elements equals to 2
for(int i=0;i<rank_of_Matrix;i++){
for(int j=0;j<rank_of_Matrix;j++){
if(A[i][j]==2){
A[i][j]=0;
}
}
}
}

My question is: how to write changed Array into Table2 after clicking button "Calculate"? Do I get it right that I need to convert float into QTableWidgetItem and then using command tbl->setItem(rank_of_Matrix,rank_of_Matrix, coppy->clone()); in loop write it into Table?

Thank you in advance!

anda_skoa
17th July 2016, 10:42
My question is: how to write changed Array into Table2 after clicking button "Calculate"?

You only have one table, "tbl"



Do I get it right that I need to convert float into QTableWidgetItem

No, you format the number as a QString and set that as the table widget item's text.
You can additionally store the actual number through setData(), using Qt::EditRole.




and then using command tbl->setItem(rank_of_Matrix,rank_of_Matrix, coppy->clone());

No, you just create a new QTableWidgetItem, passing the text as its constructor argument.



in loop write it into Table?

yes

Cheers,
_

Blitzor DDD
17th July 2016, 11:06
You only have one table, "tbl"


I meant tbl of course. I am going to use the same tbl and created it on the Widget below. Is it possible?


setData(), using Qt::EditRole.
but setDate() has type bool. http://doc.qt.io/qt-5/qabstractitemmodel.html#setData


No, you just create a new QTableWidgetItem, passing the text as its constructor argument. You can additionally store the actual number through setData(), using Qt::EditRole.


Could you please provide an example?

anda_skoa
17th July 2016, 12:07
I meant tbl of course. I am going to use the same tbl and created it on the Widget below. Is it possible?

If you want to create a new table every time the button is clicked and just keep the old table for viewing, sure, why not.



but setDate() has type bool. http://doc.qt.io/qt-5/qabstractitemmodel.html#setData

That is a different setData(), but which of the three arguments is of type bool?
I see QModelIndex, QVariant and int.



Could you please provide an example?
Sure, basic C++:


QTableWidgetItem *item = new QTableWidgetItem(text);
item->setData(Qt::EditRole, value);


Cheers,
_

Blitzor DDD
17th July 2016, 12:08
So, I tried this, but program goes out since I click "calculate"


#include "widget.h"
#include <QAbstractItemModel>

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->setGeometry(30,30,800,750);
rank = new QLineEdit("Enter the Rank", this);//rank->setGeometry(10,0,20,20);
ok = new QPushButton("Ok", this); ok->setGeometry(150, 0,80,30);
calculate = new QPushButton("calculate",this); calculate->setGeometry(250,0,80,30);



connect(ok,SIGNAL(clicked()),this,SLOT(ok_clicked( )));
connect(calculate,SIGNAL(clicked()),this,SLOT(calc ulate_clicked()));
}

Widget::~Widget()
{

}

void Widget::ok_clicked()
{

rank_of_Matrix = rank->text().toDouble();
tbl=new QTableWidget(rank_of_Matrix,rank_of_Matrix,this);
tbl->setGeometry(20,50,770,250);
tbl->show();
}

void Widget::calculate_clicked()
{
tbl_2 = new QTableWidget(rank_of_Matrix,rank_of_Matrix,this);

tbl_2 ->setGeometry(20,350,770,250);
Action_toArray();
tbl_2 ->show();
}

void Widget::Action_toArray()
{

A= new float* [rank_of_Matrix];
for(int i=0;i<rank_of_Matrix;i++){
A[i]=new float [rank_of_Matrix];
}

//read from Table 1 tbl
for(int i=0;i<rank_of_Matrix;i++){
for(int j=0;j<rank_of_Matrix;j++){

A[i][j] = tbl->item(i,j)-> data(Qt::DisplayRole).toFloat();
}
}

//operation with Array
for(int i=0;i<rank_of_Matrix;i++){
for(int j=0;j<rank_of_Matrix;j++){
if(A[i][j]==2)
{
A[i][j]=0;
}
}
}

//write to Table2 tbl_2
QVariant tableData;
for(int i=0;i<rank_of_Matrix;i++){
for(int j=0;j<rank_of_Matrix;j++){
tableData = A[i][j];
tbl_2->item(i,j)->setData(Qt::EditRole,tableData);
}
}
}

So, could you please tell me what is wrong and how I can fix it?

anda_skoa
17th July 2016, 12:52
You are accessing tbl->item(i, j), where did you create these items?
You are also accessing tbl_2->item(i, j), where did you create these items?

Cheers,
_

Blitzor DDD
17th July 2016, 13:10
I thought, that item is a function to access to element of the Table and this is not an object to create it, isn't it?

this is header-file

.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTableWidget>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTableWidgetItem>

class Widget : public QWidget
{
Q_OBJECT

public:
Widget(QWidget *parent = 0);
~Widget();

private:
QTableWidget * tbl;
QTableWidgetItem * ptwi = 0;
QTableWidgetItem * coppy;
QStringList * lst;
QLineEdit * rank;
QPushButton * ok;
QPushButton * calculate;

int rank_of_Matrix=1;
float x=0;
float **A;


private slots:
void ok_clicked();
void calculate_clicked();
void Action_toArray();
};

#endif // WIDGET_H

anda_skoa
17th July 2016, 14:01
I thought, that item is a function to access to element of the Table and this is not an object to create it, isn't it?


QTableWidget::item():


Returns the item for the given row and column if one has been set; otherwise returns 0.

You don't seem to set items anywhere, so it is most likely that you are getting a null pointer back.
You don't check for "not null" so your crash is very likely the attempted dereferencing of that null pointer.

Cheers,
_

Blitzor DDD
17th July 2016, 14:38
Ok, I added line in .h
QTableWidgetItem * item;
and in .cpp
item = new QTableWidgetItem();

but nevetherless, here:


for(int i=0;i<rank_of_Matrix;i++){
for(int j=0;j<rank_of_Matrix;j++){
//записали в массив то, что есть в таблице 1
A[i][j] = tbl->item(i,j)-> data(Qt::DisplayRole).toFloat();
qDebug() <<"А"<<i<<" "<<j<<" = "<<A[i][j];
}
}

I checked with qDebug() and it worked, data has been set into Array

and item in this loop has nothing to do with item connected to QTableWidget....

So, I still have no idea what is going on and what should I do with that...
Could you please tell me again?

anda_skoa
17th July 2016, 15:14
Ok, I added line in .h
QTableWidgetItem * item;

And you did this why?



and in .cpp
item = new QTableWidgetItem();

So you have a single tabel widget item stored in a member of the class.
How will that help solve your problem?




for(int i=0;i<rank_of_Matrix;i++){
for(int j=0;j<rank_of_Matrix;j++){
//записали в массив то, что есть в таблице 1
A[i][j] = tbl->item(i,j)-> data(Qt::DisplayRole).toFloat();
qDebug() <<"А"<<i<<" "<<j<<" = "<<A[i][j];
}
}

I checked with qDebug() and it worked, data has been set into Array

Oh, maybe you have manually entered data into that table?



So, I still have no idea what is going on and what should I do with that...
Could you please tell me again?

Check the stack trace of your program when it crashes.

I am pretty sure it crashes in


tbl_2->item(i,j)->setData(Qt::EditRole,tableData);

because you are calling setData() on a null pointer.

Cheers,
_

Blitzor DDD
17th July 2016, 15:17
Yes, you are right.
And yes I enter it manually.

Problem was solved when I changed problem line to:
tbl_2->setItem(i,j, ptwi = new QTableWidgetItem(QString::number( A[i][j] )));

d_stranz
17th July 2016, 16:05
@BlitzorDDD: You could save yourself a lot of time and head-pounding if you used Google and looked up some of the many, many examples on how to use QTableWidget:

https://wiki.qt.io/How_to_Use_QTableWidget
http://www.codeprogress.com/cpp/libraries/qt/qtClasses.php?item=QTableWidget

and you would make many fewer mistakes if you learned how to write a good Qt application by studying the examples and tutorials on the Qt web site:

http://doc.qt.io/qt-5/qtexamplesandtutorials.html

We could spend many hours fixing each new bug you create, or you could teach yourself not to make bugs in the first place.

Blitzor DDD
17th July 2016, 16:17
Yes, yes, I would and I will.
This is just my third program on Qt.
Thank you very much for your links!

anda_skoa
17th July 2016, 16:20
Yes, you are right.
And yes I enter it manually.

Which, unsurprisingly, results in items being added to the table.
Your tbl_2, on the other hand, remains empty.



Problem was solved when I changed problem line to:
tbl_2->setItem(i,j, ptwi = new QTableWidgetItem(QString::number( A[i][j] )));

Not sure what you have the "ptwi" in there for, but yes.
As already clarified in comment #2, btw.

Cheers,
_