PDA

View Full Version : Changing QPushButton Text dynamically



WanderingSoul
18th March 2015, 20:49
Hello there,
I've been working on a GUI for a simple puzzle game where the program generates
numbers for a 9x9 grid. I've represented that grid as 81 different, stylized QPushButtons
and everything works so far. When the numbers are generated, each appear in its
allocated slot. The problem occurs when the user clicks the "New Game" Menu action
button (which is supposed to "reset" the grid and generate new random numbers); the
QPushButtons retain their text and do not "reset".

Here's the code I am using to populate the GUI portion of the code:
I extract all the QPushButtons into a QList and iterate to access each one of
them (and that works fine the first time), but not when DestroyWindow()
within NewGame() is invoked....



MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close()));
connect(ui->actionNew_Game, SIGNAL(triggered()), this, SLOT(NewGame()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(About()));

InitiateWindow();
}

// actionNew_Game Signal handler
// Attempts to destroy the current puzzle and generate a new one
// NOTE: TO BE DEBUGGED, NOT FULLY FUNCTIONAL AS OF YET
void MainWindow::NewGame()
{
DestroyWindow();
InitiateWindow();
}


// Initializes the puzzle by calling an instance of Board and its puzzle
// generating functions. A list of all available QPushButtons is then
// iterated though, where every single button gets a number from the
// generated puzzle and background colour (either teal or white) depending
// whether its location is odd or even.
void MainWindow::InitiateWindow()
{
board = new Board();
board->Initialize();
board->GeneratePuzzle();
// board->DisplayInConsole();
std::vector<std::vector<int> > puzzle = board->getBoard();
QList<QPushButton*> allbuttons = this->findChildren<QPushButton*>();

int counter = 0;
int x =0; int y = 0;
int colorcount = 0;
foreach (QPushButton* button, allbuttons)
{
QString buttonname = "pushButton_" + QString::number(counter);
button->setObjectName(buttonname);
if (colorcount%2 == 0)
button->setStyleSheet("background-color: teal");
else
button->setStyleSheet("background-color: white");
if (puzzle[x][y] != -1)
button->setText(QString::number(puzzle[x][y]));
counter++,y++;colorcount++;
if (counter == board->getBoardlength())
{
x++;
y = 0;
counter = 0;
}
}
}

// Attempts to destory the current puzzle instance
// NOTE: TO BE DEBUGGED, NOT FULLY FUNCTIONAL AS OF YET
void MainWindow::DestroyWindow()
{
QString emptycell = " ";
board->~Board();
QList<QPushButton*> allbuttons = this->findChildren<QPushButton*>();
foreach (QPushButton* button, allbuttons)
button->setText(emptycell);
}

// default destructor
MainWindow::~MainWindow()
{
delete ui;
}


Any ideas? Any help would be appreciated!
Thanks!

breakthecode
18th March 2015, 23:11
try setText()

WanderingSoul
18th March 2015, 23:52
Uhm, that's what I've been doing all along, have you seen my code?

The problem is setText() doesn't override existing text.
Look at this screenshot to what happens when DestoryWindow() is called (for the sake of
demonstration, all buttons should be overridden with the same thing : "Test" ) ->

Before:
11020

After:

11021

Added after 18 minutes:

Ok Nvm, I think I found it after some extensive research.
The button must be repainted after the update, which explains why the empty ones changed and the ones who had
text didn't.
Thanks anyways!

wysota
18th March 2015, 23:54
setText() does override the previous text. If it doesn't work for you then you are either:
a) calling the method on a different object to the one you think you are calling it on
b) not calling the method at all (e.g. upon not entering a condition you think you are entering).

Hard to say which is the case here. I would probably opt for the second one (you have a 'foreach' and a couple of 'ifs').

As for repainting, setText() triggers an update() which in turn repaints the widget. So again calling setText() is enough. Then you just need to let Qt handle events like usual.

stampede
20th March 2015, 09:36
Btw. you have a memory leak:


board->~Board();

this does not release memory pointed to by "board" pointer, it only calls the destructor method.
You need to use "operator delete"


delete board;