QT :how to check if there Empty cell in qt table widget - qt

i have table widget with specific row and column ,
my function is as follow
get value from the first column and second column
compare between them and return result in the third column
Ex: first column :1 2 3 Second column 2 2 3 Result column No Yes Yes
I make sure that my code work by using the qDebug, however when I compile and run it the mainwindow stopped and crash.
I use for loop to go throw all rows for(int row=0;rowtableWidget->rowCount();row++)
I think this line rowtableWidget->rowCount() coz when it read empty cells the app Freeze and stop working .
how can I void that to happen
void MainWindow::GenerateRes() {
QString Result;
for(int row = 0; row < ui->tableWidget->rowCount(); row++) {
QString R1 = ui->tableWidget->item(row, 0)->text();
QString R2 = ui->tableWidget->item(row, 1)->text();
if(R1 == R2) {
Result = "P" ;
} else {
Result = "F" ;
}
QTableWidgetItem *Item = new QTableWidgetItem(Result);
ui->tableWidget->setItem(row, 2, Item);
qDebug() << Item;
}
}

To check whether the cell(i,j) in QTableWidget is empty or not, use isNull() or isEmpty().
Example:
for(int i=0; i < ui->tableWidget->rowCount(); i++)
{
for(int j=0; j < ui->tableWidget->columnCount(); j++)
{
bool flag = ui->tableWidget->item(i,j)->text().isNull();
if (!flag) /* the cell is not empty */
{
// do stuff
}
else /* the cell is empty */
{
// do stuff
}
}
}

maybe you should check the values returned from tableWidget::item(), because the functions can return 0 if no item is asigned to the provided coordinates, and in that case you're trying to call a method (QTableWidgetItem::text()) on a zero pointer.
Try something like:
QString R1;
QTableWidgetItem *item1(ui->tableWidget->item(row,0));
if (item1) {
R1 = item1->text();
}
// and so on...
Your code looks strange anyway, the 5th line (ui->tableWidget->rowCount()) doesn't make sense, you shouldn't be able to compile that (at least you're missing a semicolon).

Related

Arduino 'for' error

I have made a program for my Arduino which will sort an array of fifty random numbers in ascending or descending order, I think I have got it all right, but when I run it I get an error message "expected unqualified-id before 'for' ".
int array [50];
int i = 0;
void setup() {
Serial.begin(9600); // Load Serial Port
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println ("Position " + array[i]);
delay (2000);
}
for (i <= 50) { <-----*Here is where the error highlights*--->
int n = random (251); // Random number from 0 to 250
array[i] = n;
i++;
}
// Bubble sort function
void sort (int a[], int size) {
for(int i=0; i<(size-1); i++) {
for(int o=0; o<(size-(i+1)); o++) {
if(a[o] > a[o+1]) {
int t = a[o];
a[o] = a[o+1];
a[o+1] = t;
}
}
}
}
I have annotated where the error is shown. I need to get past this to test my code, I have no clue on how to fix it!
You have written it wrong. There is pseudocode of for loop:
for(datatype variableName = initialValue; condition; operation){
//your in loop code
}
//Code wich will be executed after end of for loop above
In your case it will look like this:
for(int i = 0; i < 50 ; i++){
int n = random (251); // Random number from 0 to 250
array[i] = n;
}
Another thing is, that you are trying to iterate the array. The first index is 0. It means the last index is 49 not 50. If you try to access 50th index it will crash your program.
Last thing is, that the for loop we are talking about is out of any method. It will never be executed.
The for loop requires three parts to its parameters:
A variable to count iterations
A condition that must be true to continure
A increment factor
Each part should be separated by a semicolon
So your for loop should start out like this:
for(int i = 0;i <= 50; i++){
//code here
}
Official arduino For Loop Reference

Game of Life Processing

import processing.core.PApplet;
public class gl extends PApplet {
static int neighborCount;
static int screenRows;
int tNC; // Temporary Neighbor Count
int newState;
int columns = 960;
int rows = 477;
int[][] cells = new int[columns][rows];
int[][] newGen = new int[columns][rows];
public static void main(String[] args) {
PApplet.main("gl");
}
public void settings() {
size(1920, 955);
}
public void setup() {
// Set background white and all of cells[][] to 0 or 1
screenRows = 0;
background(255);
for (int j = 0; j < (rows / 2); j++) {
for (int i = 0; i < (columns / 2); i++) {
cells[i][j] = (int) random(0, 2);
}
}
}
public void draw() {
// If program has finished generating this frame, reset everything and set cells[][] equal to newGen[][]
if (screenRows > (height / 2)) {
screenRows = 0;
System.out.println("End of generation reached");
background(255);
cells = newGen.clone();
for (int i = 0; i < columns; i++) {
for (int j = 0; j < rows; j++) {
newGen[i][j] = 0;
}
}
}
// Go through every element in cells[][], determine it's value, and display it
for (int x = 1; x < (width / 2) - 1; x++) {
for (int y = 1; y < (height / 2) - 1; y++) {
printCell(x, y);
}
}
screenRows++;
}
public void printCell(int x, int y) {
setCellState(x, y);
if (newGen[x][y] == 0) {
stroke(255);
fill(255);
} else if (newGen[x][y] == 1) {
stroke(0);
fill(0);
}
System.out.println(x + ", " + y);
rect(x, y, 2, 2);
}
public void setCellState(int x, int y) {
tNC = getNeighborCount(x, y);
neighborCount = 0;
System.out.println(tNC);
if (tNC < 2) { // If less than 2 neighbors, cell dead
newGen[x][y] = 0;
} else if (tNC > 3) { // If more than 3 neighbors, cell dead
newGen[x][y] = 0;
} else if ((tNC == 2 || tNC == 3) && cells[x][y] == 1) { // If 2 or 3 neighbors and cell is alive, do nothing (unnecessary statement but makes visualizing easier)
} else if (tNC == 3 && cells[x][y] == 0) { // If 3 neighbors and cell is dead, cell is alive
newGen[x][y] = 1;
} else if (tNC == 2 && cells[x][y] == 0) { // If 2 neighbors and cel is dead, do nothing (also unnecessary)
} else {
System.out.println("Error in setCellState(int, int);"); // In event of none of the conditions being met
}
tNC = 0; // Reset variable (probably unnecessary but might as well)
}
public int getNeighborCount(int x, int y) {
// Go through each cell adjacent or diagonal to the cell and add it's value (0 or 1) to neighborCount
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
neighborCount += cells[i + x][j + y];
}
}
// Subtract the value of the cell being evaluated from neighborCount as that is not a factor in the sum of the neighbors
neighborCount -= cells[x][y];
return neighborCount;
}
}
Pastebin
I am just going for functionality over speed, for now.
I am attempting to code Conway's Game of Life using Processing in Eclipse. The above code is dysfunctional in multiple ways:
The generation displayed appears much smaller in the window than I want to be. It only takes up a fraction of the window despite my efforts to counterbalance this by making each cell 2x2 pixels and half as many rows and columns as the window is tall and wide.
Also, the generation does not appear to update in the window after the first generation is displayed after a few seconds.
I noticed that the variable tNC is often equal to 0 when it should be equal to any number from 0 to 7.
You've got three main problems.
Problem 1: You seem to be generating the next generation as you render cells, which might be okay... but then what are you doing with the screenRows logic (the if statement in your draw() function)?
If I were you, I would split your logic up into two sections: write one function that draws your board, and another function that returns a new board based on the current one. Stop trying to calculate the next generation as you're drawing the current generation, as that's just going to give you a ton of headaches.
I also don't think your logic for switching between the arrays is correct. Which array holds the current generation, and which holds the next generation? Are you sure?
Problem 2: You seem to be switching between pixel sizes and array coordinates. For example, you're drawing each cell at its array index coordinate, but you're drawing them as 2x2 rectangles. This doesn't make a ton of sense, since you're just going to draw over top of it with the next cell anyway. Again, separate your logic: create a function that draws a cell based on the window width and height, an array position, and an array length.
Problem 3: Your print statements are killing your framerate. Print statements are notoriously slow. Your framerate is already pretty slow because of all of the calculations you're doing, but it gets even slower when you print out (960*477*2) things every single frame. This isn't really a logic error, but it makes it harder to see exactly what your program is doing.
The Solution: To fix your problems, I'd recommend refactoring your code quite a bit. If I were you, I would start over with a new program. Then:
Step 1: Separate your drawing logic from your logic for calculating the next generation. Create two functions: one for drawing, and another one that returns a new array based on the current one.
Step 2: In your drawing code, make sure you separate your array indexes and your pixel positions. Maybe write another function that takes a cell position and draws a rectangle based on the window size and the array size.
PS: Are you in the same class as this person? Are you using Daniel Shiffman's code too?

How to print a vector in plain text in QT

int b=0;
QVector<int> z(5);
for(int i=0;i<5;i++)
z.push_back(i);
for(int i=0;i<z.size();i++)
{
b=z.at(i);
QString str=QString::number(b);
ui->mbox->setText(str);
}
I wrote this code to print a vector in plain text but it just print first row I want to print
whole vector
not:mbox is a plain textedit
now there is another problem
QVector<int> z(5);
for(int i=0;i<5;i++)
z.push_back(i);
QString str;
for (int i = 0; i < z.size(); ++i)
{
if (i > 0)
str += " ";
str += QString::number(z[i]);
}
ui->mbox->setText(str);
}
in first for loop when I wrote z.size() I get Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.
and also in second for when I wrote z.size I get 10 output but size of z is 5 as you can see .what is wrog
first 5 output is 0 and then rest is normal like 0 1 2 3 4
but I should have 5 output am I wrong
You are overwriting the text for every item in the vector. Construct a QString from the values like this:
QString str;
for (int i = 0; i < z.size(); ++i)
{
if (i > 0)
str += " ";
str += QString::number(z[i]);
}
ui->mbox->setText(str);

Qt - SelectedItems in QTableView

I'm trying to return a vector of selected rows from a QTableView widget(snippet copied below), however the values returned do not correspond to the selection and I believe I've not understood QModelIndexList/QModelIndex with respect to QTableView. Can you let me know where I'm wrong or the right way to access selected items from a QTableView?
C_model is of type QStandardItemModel
for(int i = 0; i < c_model->rowCount(); i++)
{
if (selectionModel->isRowSelected(i, QModelIndex()))
{
QStringList selection;
std::vector<std::string> currentIndexValues;
for (int j = 0; j < c_model->columnCount(); j++)
{
QVariant q = c_model->data(c_model->index(i, j));
selection.append(q.toString());
currentIndexValues.push_back(q.toString().toLocal8Bit().constData());
printf(" %s\t ", currentIndexValues[j].c_str());
}
printf("\n");
v_selectedItems.push_back(currentIndexValues);
}
}
Thanks
QAbstractItemView (the base class of QTableView) offers a QItemSelectionModel for this purpose. You can access that model via QTableView::itemSelectionModel() and then retrieve the selected rows via QItemSelectionModel::selectedRows():
QModelIndexList selectedRows = yourTableView->selectionModel()->selectedRows();
foreach( QModelIndex index, selectedRows )
{
int row = index.row();
}

Populating Table Widget from Text File in Qt

I'm new to Qt and need some help with the following:
I would like to create a GUI containing a Table Widget that is populated by information coming from a tab delimited text file. In my GUI, the user would first browse for the text file and then it would then show the contents in the Table Widget. I've done the browse part, but how do I load the data from the text file into the Table Widget?
It's two steps, parse the file, and then push it into the widget.
I grabbed these lines from the QFile documentation.
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
QByteArray line = file.readLine();
process_line(line);
}
Your process_line function should look like this:
static int row = 0;
QStringList ss = line.split('\t');
if(ui->tableWidget->rowCount() < row + 1)
ui->tableWidget->setRowCount(row + 1);
if(ui->tableWidget->columnCount() < ss.size())
ui->tableWidget->setColumnCount( ss.size() );
for( int column = 0; column < ss.size(); column++)
{
QTableWidgetItem *newItem = new QTableWidgetItem( ss.at(column) );
ui->tableWidget->setItem(row, column, newItem);
}
row++;
For more information about manipulating QTableWidgets, check the documentation. For new users using the GUI builder in Qt Creator, it is tricky figuring it out at first.
Eventually I would recommend to switching to building the GUI the way they do in all their examples... by adding everything by hand in the code instead of dragging and dropping.
Sorry...
void squidlogreader_::process_line(QString line)
{
static int row = 0;
QStringList ss = line.split('\t');
if(ui->tableWidget->rowCount() < row + 1)
ui->tableWidget->setRowCount(row + 1);
if(ui->tableWidget->columnCount() < ss.size())
ui->tableWidget->setColumnCount( ss.size() );
for( int column = 0; column < ss.size(); column++)
{
QTableWidgetItem *newItem = new QTableWidgetItem( ss.at(column) );
ui->tableWidget->setItem(row, column, newItem);
}
row++;
}
void squidlogreader_::on_pushButton_clicked()
{
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
QString line = file.readLine();
process_line(line);
}

Resources