PDA

View Full Version : putting QTableWidgetItem (s) in a boolean array



hichemnho
14th February 2012, 20:10
Hello,
As the title is saying , I am trying to put the result of a user input , in a QTableWidget, and take this QTableWidget to fillin an array.
I have read the documentation but infortunetly I can not do it .
Here is the code:


//the header
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
#include <vector>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();
bool M[2][2];
QTableWidgetItem * element;
private slots:
private:
QTableWidget* tableWidget;


};
#endif



//FenPrincipale.cpp



#include "qDebug.h"
#include "FenPrincipale.h"


FenPrincipale::FenPrincipale()
{
int o,p;

tableWidget = new QTableWidget(2,2,this);
element = new QTableWidgetItem (1000);
for (o=0; o<2; o++)
{
for (p=0; p<2; p++)
{
(M[o][p])=false;

}
}

for (o=0; o<2; o++)
{
for (p=0; p<2; p++)
{
element=(tableWidget->itemAt((o+1),(p+1)));
if ((element->toString)="1")
{
M[o][p]=true;
}
else
{
M[o][p]=false;
}
}
}

}


//main.cpp


#include <QApplication>
#include "FenPrincipale.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);

FenPrincipale fenetre;
fenetre.show();
return app.exec();
}




Thank you very much for the attention given to this message.

KillGabio
15th February 2012, 02:59
What is the error? isn`t the program going out of boundries with that +1??Are you sure its a custom type bool(as you are passing the 1000 to the constructor)?

hichemnho
15th February 2012, 07:38
Thank you for your answer :
here is a modification of the Fenprincipale.cpp , but it is still not working:



//FenPrincipale.cpp


#include "qDebug.h"
#include "FenPrincipale.h"


FenPrincipale::FenPrincipale()
{
int o,p;

tableWidget = new QTableWidget(2,2,this);
element = new QTableWidgetItem (1000);
for (o=0; o<2; o++)
{
for (p=0; p<2; p++)
{
(M[o][p])=false;

}
}

for (o=0; o<2; o++)
{
for (p=0; p<2; p++)
{
element=(tableWidget->item((o+1),(p+1)));
if ((element->text())=="1")
{
M[o][p]=true;
}
else
{
M[o][p]=false;
}
}
}

}




Thank you in advance for your help.

myta212
15th February 2012, 07:55
Hi,
Use QTableWidget->item,
Because QTableWidget->itemAt use coordinat location.
Please check this code :



ui->tableWidget->setRowCount(2);
ui->tableWidget->setColumnCount(2);

int i,j;
for(i=0; i<2; i++)
{
for(j=0; j<2; j++)
{
QTableWidgetItem *item = new QTableWidgetItem(QString::number(i));
ui->tableWidget->setItem(i,j,item);

}
}

QTableWidgetItem *item;
for(i=0; i<2; i++)
{
for(j=0; j<2; j++)
{
item = ui->tableWidget->item(i,j);
ui->textEdit->append(item->text());

if (item->text()="1")
{
M[o][p]=true;
}
else
{
M[o][p]=false;
}

}
}


you can modified with your problem. This code return text value from QTableWidget

Thank you

Best regards,

Myta

hichemnho
15th February 2012, 17:19
Thank you very much ,

I tried this code but an error occured because of ui .
Can you please tell me what "ui" means?
Thank you

KillGabio
15th February 2012, 17:57
basically UI represents all the objects created with the QDesigner...

http://developer.qt.nokia.com/doc/qt-4.8/qt-gui-concepts.html

a recommendation: google what you dont know, ask what you cant find :D

hichemnho
15th February 2012, 18:04
Thanks,
I tried to put "this" (which means fenetre in my case ) instead of "ui" , but it is still not working.
Thank you again.

KillGabio
15th February 2012, 18:09
this->

should work because you have the table widget declared in your .h :/

post the code


remember to post with
please

hichemnho
15th February 2012, 18:34
Thanks a lot,
Please check also the header maybe the error came from there.
Here is the code :


#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
#include <vector>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();
bool M[2][2];
QTableWidgetItem * element;
private slots:
private:
QTableWidget* tableWidget;



};
#endif
//FenPrincipale.cpp


//FenPrincipale.cpp


#include "qDebug.h"
#include "FenPrincipale.h"


FenPrincipale::FenPrincipale()
{
this->tableWidget->setRowCount(2);
this->tableWidget->setColumnCount(2);

int i,j;
for(i=0; i<2; i++)
{
for(j=0; j<2; j++)
{
QTableWidgetItem *item = new QTableWidgetItem(QString::number(i));
this->tableWidget->setItem(i,j,item);

}
}

QTableWidgetItem *item;
for(i=0; i<2; i++)
{
for(j=0; j<2; j++)
{
item = this->tableWidget->item(i,j);
this->textEdit->append(item->text());

if (item->text()="1")
{
M[o][p]=true;
}
else
{
M[o][p]=false;
}

}
}

}
//main.cpp


#include <QApplication>
#include "FenPrincipale.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);

FenPrincipale fenetre;
fenetre.show();
return app.exec();
}





Thanks one more time.

The errors are:
- C:\Users\SHADUS\fortementc\tabl\FenPrincipale.cpp: 33: erreur : 'class FenPrincipale' has no member named 'textEdit'
- C:\Users\SHADUS\fortementc\tabl\FenPrincipale.cpp: 35: erreur : could not convert 'QTableWidgetItem::text() const().QString::operator=(((const char*)"1"))' to 'bool'

the error after correction of error at line 35 (one"=" was missing) is:
- 'class FenPrincipale' has no member named 'textEdit'

KillGabio
15th February 2012, 19:01
Well if you read that error carefully it means you havent declared textEdit... try delcaring QString textEdit

The seccond error one equals means declare, two equals (==) means comparison ;)

hichemnho
15th February 2012, 19:12
Thank you for your time,
I only modified the header :


#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
#include <vector>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();
bool M[2][2];
QTableWidgetItem * element;
private slots:
private:
QTableWidget* tableWidget;
QString * textEdit;



};
#endif


after compiling , the program crash and stops.

KillGabio
15th February 2012, 20:03
Well of course, just think for a moment what you are doing...you are trying to retrieve an item from a table that its not initialized...you just declare the size of the table but the fields are never set to a valid value...

hichemnho
15th February 2012, 20:07
Thanks for your response ,
I am a beginner in Qt and C++ so please tell me exactly what is wrong.

KillGabio
15th February 2012, 23:18
It`s like real life, you claim to have a millon dollars but actually you dont (I guess, lol) in this case you delcare a table but you never declare it...YOU CANNOT USE ANYTHING YOU HAVENT DECLARED BEFORE ....try adding this before setting the rowCount...


tableWidget = new QTableWidget (this);

its a very common mistake dont worry but try to read some more about c++ specially

ChrisW67
16th February 2012, 00:35
Your original code creates a table widget at line 34 and a new element at line 35. The code never puts anything in the table widget. The table widget will not be seen by the user before (line 46) you start trying to extract items from the unfilled widget. At line 50 you are using the itemAt() function, which gives the cell at certain screen coordinates (it isn't visible here), when you want the item() function that returns the item in a particular table cell. Accessing the unfilled table will, at best, give you an item containing a null QVariant() value and at worst a null pointer. As KillGabio pointed out, you also try to retrieve elements from row/column 1 or 2 of a table (line 50) that only has to row/column 0 or 1. This will return a null pointer (line 50) and your subsequent (line 51) use of the pointer will crash the program.

myta212 has provided an example of loading the table widget with data..

You really need to step back from the problem, polish up your C++, look at how Qt is supposed to operate, and then break the problem up into pieces. Here is an example that show one way to approach your matrix editor (I have left your matrix data structure alone)..



#include <QtGui>
#include <QDebug>

class MatrixWidget: public QTableWidget {
Q_OBJECT

public:
MatrixWidget(QWidget *p = 0): QTableWidget(p) {
setRowCount(2);
setColumnCount(2);

// Default population
for (int r = 0; r < 2; ++r) {
for (int c = 0; c < 2; ++c) {
QTableWidgetItem *it = new QTableWidgetItem;
it->setData(Qt::EditRole, 0);
setItem(r, c, it);
}
}
}

void setData(bool M[2][2]) {
for (int r = 0; r < 2; ++r) {
for (int c = 0; c < 2; ++c) {
QTableWidgetItem *it = item(r, c);
Q_ASSERT(it);
int val = M[r][c]? 1: 0;
it->setData(Qt::EditRole, val);
}
}
}

void getData(bool M[2][2]) {
for (int r = 0; r < 2; ++r) {
for (int c = 0; c < 2; ++c) {
QTableWidgetItem *it = item(r, c);
Q_ASSERT(it);
int val = it->data(Qt::EditRole).toInt();
M[r][c] = (val == 1)? true: false;
}
}
}
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

bool M[2][2] = { {false, true}, {true, false} };

MatrixWidget m;
m.setData(M);
m.show();
return app.exec();
}
#include "main.moc"

hichemnho
16th February 2012, 08:50
Hello,


I tried to think differently and I came up with the fact that after filling the QTableWidget I push a QPushButton to generate the slot "FillIn" to fill the matrixe M but it does not work.
The error is : QTableWidget: cannot insert an item that is already owned by another QTableWidget
Here is the code:


//The modified header
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
#include <vector>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();
bool M[2][2];

private slots:
void FillIn();
private:
QTableWidget *tabM;
QTableWidgetItem *it;
QPushButton * generer;
};
#endif




//FenPrincipale.cpp
#include "qDebug.h"
#include "FenPrincipale.h"
FenPrincipale::FenPrincipale()
{

QTableWidget *tabM =new QTableWidget(this);
tabM->setRowCount(2);
tabM->setColumnCount(2);
generer = new QPushButton("&Générer !",this);
generer->move(50,50);
QTableWidgetItem *it = new QTableWidgetItem;


for (int r = 0; r < 2; ++r) {
for (int c = 0; c < 2; ++c) {


tabM->setItem(r, c, it);
it->setData(Qt::EditRole, 0);
//qDebug() <<it;
}
}

connect(generer, SIGNAL(clicked()), this, SLOT(FillIn()));
}
void FenPrincipale::FillIn()
{
for (int r = 0; r < 2; ++r) {
for (int c = 0; c < 2; ++c) {

Q_ASSERT(it);
int val = it->data(Qt::EditRole).toInt();
M[r][c] = (val == 1)? true: false;
}
}
}
//main.cpp


#include <QApplication>
#include "FenPrincipale.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);

FenPrincipale fenetre;
fenetre.show();
return app.exec();
}






By the way , why after compiling only the first cell of the QTableWidget is initializes with "0" and not the others.
Thank you very much for your attention and time.

KillGabio
16th February 2012, 14:32
Think for a moment the error: its telling you that the *it var is used before...so basically it explains what you are doing..you need to create a new item for every cell:





for (int r = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {

QTableWidgetItem *it = new QTableWidgetItem;
tabM->setItem(r, c, it);
it->setData(Qt::EditRole, 0);
}
}

and remove *it from the header (.h) if you are going to do it that way...and do r++/c++ instead of what you have if you are using the variables inside the for...

hichemnho
16th February 2012, 15:10
Hello,
Thank tou for your help , I really apreciate it.
I change the program.
Unfortunetly the variable "val" stay at "0" even if I inser "1" in the correspondant cell in the QTableWidget.


//the modified header
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
#include <vector>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();
bool M[2][2];

private slots:
void FillIn();
private:
QTableWidget *tabM;
//QTableWidgetItem *it;
QPushButton * generer;
};
#endif




//FenPrincipale.cpp
//FenPrincipale.cpp
#include "qDebug.h"
#include "FenPrincipale.h"
FenPrincipale::FenPrincipale()
{

QTableWidget *tabM =new QTableWidget(this);
tabM->setRowCount(2);
tabM->setColumnCount(2);
generer = new QPushButton("&Générer !",this);
generer->move(50,50);

for (int r = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {

QTableWidgetItem *it = new QTableWidgetItem;
tabM->setItem(r, c, it);
it->setData(Qt::EditRole, 0);
//qDebug() <<it;
}
}

connect(generer, SIGNAL(clicked()), this, SLOT(FillIn()));
}
void FenPrincipale::FillIn()
{
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {
QTableWidgetItem *it = new QTableWidgetItem;
Q_ASSERT(it);
int val = it->data(Qt::EditRole).toInt();
M[r][c] = (val == 1)? true: false;

qDebug() <<val;
}
}
}

Can you please tell me why the value of val is not updated.
Thank you.

ChrisW67
16th February 2012, 23:47
What item are you reading the value from? What is line 54 doing?

I suggest you go back and read my example's (http://www.qtcentre.org/threads/47418-putting-QTableWidgetItem-(s)-in-a-boolean-array?p=214111#post214111) getData() function more closely.

myta212
17th February 2012, 03:53
Hi,
I think you must read documentation about C++ and Qt first. Your problem is very simple, and we send you code how to solve your problem.
The problem for your question is not "putting QTableWidgetItem (s) in a boolean array" but "How to Fill And Get Value from QTableWidget".
If you want to get full code for your problem, you can get at Qt Documentation.

But, please read the other answer above. You can use :

tableWidget->setItem(i,j,item); to set Item in QTableWidget and

QTableWidgetItem *item = tableWidget->item(i,j); to get item from QTableWidget.

Please try and you will get how simple your problem.
Good luck.

Best regards,

Myta212

hichemnho
17th February 2012, 10:47
Thank you for your response,
val receives finally the value filled in the QTablWidget but there are an error that occured while the instruction of debugg is executed :QTableWidget: cannot insert an item that is already owned by another QTableWidget




//le header
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H
#include <QtGui>
#include <vector>
class FenPrincipale : public QWidget
{
Q_OBJECT
public:
FenPrincipale();
bool M[2][2];

private slots:
void FillIn();
private:
QTableWidget *tabM;
//QTableWidgetItem *it;
QPushButton * generer;
QVBoxLayout * vbox;
};
#endif

//FenPrincipale.cpp
#include "qDebug.h"
#include "FenPrincipale.h"
FenPrincipale::FenPrincipale()
{

// QTableWidget *tabM =new QTableWidget(this);
tabM =new QTableWidget(this);
tabM->setRowCount(2);
tabM->setColumnCount(2);
generer = new QPushButton("&Générer !",this);
// generer->move(50,50);
QVBoxLayout* vbox = new QVBoxLayout();
vbox->addWidget(generer);
vbox->addWidget(tabM);
this->setLayout(vbox);

for (int r = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {

QTableWidgetItem *it = new QTableWidgetItem;
tabM->setItem(r, c, it);
it->setData(Qt::EditRole, 0);
//qDebug() <<it;
}
}

connect(generer, SIGNAL(clicked()), this, SLOT(FillIn()));
}
void FenPrincipale::FillIn()
{
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 2; c++) {
QTableWidgetItem *it =new QTableWidgetItem;

it = tabM->item(r,c);

Q_ASSERT(it);

it=(tabM->item(r,c));
tabM->setItem(r, c, it);
qDebug() <<it;
int val = (it->data(Qt::EditRole)).toInt();
M[r][c] = (val == 1)? true: false;

qDebug() <<M[r][c];
}
}
}



//main.cpp


#include <QApplication>
#include "FenPrincipale.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);

FenPrincipale fenetre;
fenetre.show();
return app.exec();
}

Could you please help me find out the where the problem is beacause even if I create an QTableWidgetItem for every (r,c) the problem remains.
Thank you in advance for your help.

hichemnho
17th February 2012, 13:07
The problem is solved by erazing some useless lines .
Here is the code:


//header
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H

#include <QtGui>

class FenPrincipale : public QWidget
{
Q_OBJECT

public:
FenPrincipale();
bool M[2][2];

private slots:
void FillIn();

private:
QTableWidget *tabM;
QPushButton *generer;
};

#endif


//FenPrincipale.cpp
#include <QDebug>
#include "FenPrincipale.h"

FenPrincipale::FenPrincipale()
{
tabM =new QTableWidget(2, 2, this);
generer = new QPushButton("&Générer !",this);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(generer);
vbox->addWidget(tabM);
setLayout(vbox);

for (int r = 0; r < tabM->rowCount(); r++) {
for (int c = 0; c < tabM->columnCount(); c++) {
QTableWidgetItem *it = new QTableWidgetItem;
tabM->setItem(r, c, it);
it->setData(Qt::EditRole, 0);
}
}

connect(generer, SIGNAL(clicked()), this, SLOT(FillIn()));
}

void FenPrincipale::FillIn()
{
for (int r = 0; r < tabM->rowCount(); r++) {
for (int c = 0; c < tabM->columnCount(); c++) {
QTableWidgetItem *it = tabM->item(r,c);
Q_ASSERT(it);
qDebug() << it;
int val = (it->data(Qt::EditRole)).toInt();
M[r][c] = (val == 1) ? true : false;
qDebug() << M[r][c];
}
}
}


//main.cpp
#include <QApplication>
#include "FenPrincipale.h"

int main(int argc, char* argv[])
{
QApplication app(argc, argv);

FenPrincipale fenetre;
fenetre.show();
return app.exec();
}

Thank you all for your help , I really apreciate it .
Thank you again .

hello,
The problem is solved erazing some useless lines.
Here is the code:


//header
#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H

#include <QtGui>

class FenPrincipale : public QWidget
{
Q_OBJECT

public:
FenPrincipale();
bool M[2][2];

private slots:
void FillIn();

private:
QTableWidget *tabM;
QPushButton *generer;
};

#endif






//FenPrincipale.cpp
#include <QDebug>
#include "FenPrincipale.h"

FenPrincipale::FenPrincipale()
{
tabM =new QTableWidget(2, 2, this);
generer = new QPushButton("&Générer !",this);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(generer);
vbox->addWidget(tabM);
setLayout(vbox);

for (int r = 0; r < tabM->rowCount(); r++) {
for (int c = 0; c < tabM->columnCount(); c++) {
QTableWidgetItem *it = new QTableWidgetItem;
tabM->setItem(r, c, it);
it->setData(Qt::EditRole, 0);
}
}

connect(generer, SIGNAL(clicked()), this, SLOT(FillIn()));
}

void FenPrincipale::FillIn()
{
for (int r = 0; r < tabM->rowCount(); r++) {
for (int c = 0; c < tabM->columnCount(); c++) {
QTableWidgetItem *it = tabM->item(r,c);
Q_ASSERT(it);
qDebug() << it;
int val = (it->data(Qt::EditRole)).toInt();
M[r][c] = (val == 1) ? true : false;
qDebug() << M[r][c];
}
}
}


//main.cpp
#include <QApplication>
#include "FenPrincipale.h"

int main(int argc, char* argv[])
{
QApplication app(argc, argv);

FenPrincipale fenetre;
fenetre.show();
return app.exec();
}

Thank you all for your help.
I really apreciate it .
Thanks.