Call another widget application on QPushButton - c++

I want call another widget application calculator on pushbutton. Till this time I get success but it overlap on parent widget.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
class QLineEdit;
class QComboBox;
class calculator;
namespace Ui {
class MainWindow;
}
class MainWindow : public QWidget
{
Q_OBJECT
public:MainWindow();
public slots:
void calcButtonPressed();
private:
calculator *calc;
};
#endif // MAINWINDOW_H
and mainwindow.cpp
MainWindow::MainWindow(){
....
QPushButton *calcButton = new QPushButton(tr("Calc"));
connect(calcButton,SIGNAL(clicked(bool)),this,SLOT(calcButtonPressed()));
....
}
void MainWindow::calcButtonPressed(){
calc = new calculator(this);
calc->show();
}
calculator.cpp
#include<QtWidgets>
#include<cmath>
#include "button.h"
#include "calculator.h"
calculator::calculator(QWidget *parent): QWidget(parent)
{
sumInMemory=0.0;
sumSoFar=0.0;
factorSoFar=0.0;
waitingForOperand=true;
display=new QLineEdit("0");
display->setReadOnly(true);
display->setAlignment(Qt::AlignRight);
display->setMaxLength(15);
QFont font=display->font();
font.setPointSize(font.pointSize()+8);
display->setFont(font);
for (int i = 0; i < NumDigitButton; ++i) {
digitButton[i] = createButton(QString::number(i), SLOT(digitClicked()));
}
button *pointButton =createButton(tr("."),SLOT(pointClicked()));
button *changeSignButton=createButton(tr("\30\261"),SLOT(changeSignClicked()));
button *backspaceButton=createButton(tr("Backspace"),SLOT(backspaceClicked()));
button *clearButton=createButton(tr("Clear"),SLOT(clear()));
button *clearAllButton=createButton(tr("Clear All"),SLOT(clearAll));
button *clearMemoryButton=createButton(tr("MC"),SLOT(clearMemory()));
button *readMemoryButton=createButton(tr("MR"),SLOT(readMemory()));
button *setMemoryButton=createButton(tr("MS"),SLOT(setMemory()));
button *addToMemoryButton=createButton(tr("M+"),SLOT(addToMemory()));
button *divisionButton = createButton(tr("\303\267"), SLOT(multiplicativeOperatorClicked()));
button *timesButton = createButton(tr("\303\227"), SLOT(multiplicativeOperatorClicked()));
button *minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));
button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
button *squareRootButton = createButton(tr("Sqrt"), SLOT(unaryOperatorClicked()));
button *powerButton = createButton(tr("x\302\262"), SLOT(unaryOperatorClicked()));
button *reciprocalButton = createButton(tr("1/x"), SLOT(unaryOperatorClicked()));
button *equalButton = createButton(tr("="), SLOT(equalClicked()));
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
mainLayout->addWidget(display, 0, 0, 1, 6);
mainLayout->addWidget(backspaceButton, 1, 0, 1, 2);
mainLayout->addWidget(clearButton, 1, 2, 1, 2);
mainLayout->addWidget(clearAllButton, 1, 4, 1, 2);
mainLayout->addWidget(clearMemoryButton, 2, 0);
mainLayout->addWidget(readMemoryButton, 3, 0);
mainLayout->addWidget(setMemoryButton, 4, 0);
mainLayout->addWidget(addToMemoryButton, 5, 0);
for (int i = 1; i < NumDigitButton; ++i) {
int row = ((9 - i) / 3) + 2;
int column = ((i - 1) % 3) + 1;
mainLayout->addWidget(digitButton[i], row, column);
}
mainLayout->addWidget(digitButton[0], 5, 1);
mainLayout->addWidget(pointButton, 5, 2);
mainLayout->addWidget(changeSignButton, 5, 3);
mainLayout->addWidget(divisionButton, 2, 4);
mainLayout->addWidget(timesButton, 3, 4);
mainLayout->addWidget(minusButton, 4, 4);
mainLayout->addWidget(plusButton, 5, 4);
mainLayout->addWidget(squareRootButton, 2, 5);
mainLayout->addWidget(powerButton, 3, 5);
mainLayout->addWidget(reciprocalButton, 4, 5);
mainLayout->addWidget(equalButton, 5, 5);
setLayout(mainLayout);
setWindowTitle(tr("calculator"));
}
void calculator::digitClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
int digitValue = clickedButton->text().toInt();
if (display->text() == "0" && digitValue == 0.0)
return;
if (waitingForOperand) {
display->clear();
waitingForOperand = false;
}
display->setText(display->text() + QString::number(digitValue));
}
void calculator::unaryOperatorClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
double result = 0.0;
if (clickedOperator == tr("Sqrt")) {
if (operand < 0.0) {
abortOperation();
return;
}
result = std::sqrt(operand);
} else if (clickedOperator == tr("x\302\262")) {
result = std::pow(operand, 2.0);
} else if (clickedOperator == tr("1/x")) {
if (operand == 0.0) {
abortOperation();
return;
}
result = 1.0 / operand;
}
display->setText(QString::number(result));
waitingForOperand = true;
}
void calculator::additiveOperatorClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
return;
}
display->setText(QString::number(factorSoFar));
operand = factorSoFar;
factorSoFar = 0.0;
pendingMultiplicativeOperator.clear();
}
if (!pendingAdditiveOperator.isEmpty()) {
if (!calculate(operand, pendingAdditiveOperator)) {
abortOperation();
return;
}
display->setText(QString::number(sumSoFar));
} else {
sumSoFar = operand;
}
pendingAdditiveOperator = clickedOperator;
waitingForOperand = true;
}
void calculator::multiplicativeOperatorClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
return;
}
display->setText(QString::number(factorSoFar));
} else {
factorSoFar = operand;
}
pendingMultiplicativeOperator = clickedOperator;
waitingForOperand = true;
}
void calculator::equalClicked()
{
double operand = display->text().toDouble();
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
return;
}
operand = factorSoFar;
factorSoFar = 0.0;
pendingMultiplicativeOperator.clear();
}
if (!pendingAdditiveOperator.isEmpty()) {
if (!calculate(operand, pendingAdditiveOperator)) {
abortOperation();
return;
}
pendingAdditiveOperator.clear();
} else {
sumSoFar = operand;
}
display->setText(QString::number(sumSoFar));
sumSoFar = 0.0;
waitingForOperand = true;
}
void calculator::pointClicked()
{
if (waitingForOperand)
display->setText("0");
if (!display->text().contains('.'))
display->setText(display->text() + tr("."));
waitingForOperand = false;
}
void calculator::changeSignClicked()
{
QString text = display->text();
double value = text.toDouble();
if (value > 0.0) {
text.prepend(tr("-"));
} else if (value < 0.0) {
text.remove(0, 1);
}
display->setText(text);
}
void calculator::backspaceClicked()
{
if (waitingForOperand)
return;
QString text = display->text();
text.chop(1);
if (text.isEmpty()) {
text = "0";
waitingForOperand = true;
}
display->setText(text);
}
void calculator::clear()
{
display->setText("0");
waitingForOperand = true;
}
void calculator::clearAll()
{
sumSoFar = 0.0;
factorSoFar = 0.0;
pendingAdditiveOperator.clear();
pendingMultiplicativeOperator.clear();
display->setText("0");
waitingForOperand = true;
}
void calculator::clearMemory()
{
sumInMemory = 0.0;
}
void calculator::readMemory()
{
display->setText(QString::number(sumInMemory));
waitingForOperand = true;
}
void calculator::setMemory()
{
equalClicked();
sumInMemory = display->text().toDouble();
}
void calculator::addToMemory()
{
equalClicked();
sumInMemory += display->text().toDouble();
}
button *calculator::createButton(const QString &text, const char *member)
{
button *button1 = new button(text);
connect(button1, SIGNAL(clicked()), this, member);
return button1;
}
void calculator::abortOperation()
{
clearAll();
display->setText(tr("####"));
}
bool calculator::calculate(double rightOperand, const QString &pendingOperator)
{
if (pendingOperator == tr("+")) {
sumSoFar += rightOperand;
} else if (pendingOperator == tr("-")) {
sumSoFar -= rightOperand;
} else if (pendingOperator == tr("\303\227")) {
factorSoFar *= rightOperand;
} else if (pendingOperator == tr("\303\267")) {
if (rightOperand == 0.0)
return false;
factorSoFar /= rightOperand;
}
return true;
}
I get output as calculator overlaps on mainwindow widget.
Can I get separate window for calculator?

You must change calc = new calculator(this) to calc = new calculator().

From Qt documentation
QWidget::QWidget ( QWidget * parent = 0, Qt::WindowFlags f = 0 )
Constructs a widget which is a child of parent, with widget flags set
to f.
If parent is 0, the new widget becomes a window. If parent is another
widget, this widget becomes a child window inside parent. The new
widget is deleted when its parent is deleted.
Do not supply parent when constructing calculator, then it would become separate top-level window

Related

How to reset values after dying

I am making a google chrome dinosaur game using an SDL Template for graphics and I am almost finished but I have run into the issue of needing to be able to reset to the starting values of the game just like how you reset when you hit spacebar after dying in the google chrome dinosaur game. I have made an isGameOver function but I don't know how to reset the values to start a new game which is my main problem.
this is my GameScene class where the game over logic is located
GameScene.h
#pragma once
#include "Scene.h"
#include "GameObject.h"
#include "Player.h"
#include "Floor.h"
#include "Obstacle.h"
#include "FlyingObstacle.h"
#include <vector>
#include "util.h"
#include "text.h"
class GameScene : public Scene
{
public:
GameScene();
~GameScene();
void start();
void draw();
void update();
std::vector<Obstacle*> spawnedObstacle;
std::vector<FlyingObstacle*> spawnedBird;
private:
Player* player;
Floor* floor;
float spawnTime;
float currentSpawnTimer;
void floorCollision();
void obstacleCollision();
void birdCollision();
void obstacleSpawn();
void birdSpawn();
void despawnObstacle(Obstacle* obstacle);
void despawnBird(FlyingObstacle* bird);
int points;
int highscore;
bool isGameOver;
};
GameScene.cpp
#include "GameScene.h"
GameScene::GameScene()
{
// Register and add game objects on constructor
player = new Player();
this->addGameObject(player);
floor = new Floor();
this->addGameObject(floor);
points = 0;
highscore = 0;
}
GameScene::~GameScene()
{
delete player;
}
void GameScene::start()
{
Scene::start();
// Initialize any scene logic here
initFonts();
isGameOver = true;
currentSpawnTimer = 300;
spawnTime = rand() % 300; //spawn time of 5 seconds
for (int i = 0; i < 1; i++)
{
obstacleSpawn();
}
for (int i = 0; i < 3; i++)
{
birdSpawn();
}
}
void GameScene::draw()
{
Scene::draw();
drawText(110, 20, 255, 255, 255, TEXT_CENTER, "POINTS: %03d", points);
if (player->getIsAlive() == true)
{
drawText(900, 20, 255, 255, 255, TEXT_CENTER, "PRESS SPACE TO START MOVING");
}
if (player->getIsAlive() == false)
{
if (isGameOver == false)
drawText(SCREEN_WIDTH / 2, 200, 255, 255, 255, TEXT_CENTER, "YOU LOSE! PRESS SPACE TO SHOW POINTS");
if (isGameOver == true)
{
drawText(SCREEN_WIDTH / 2, 200, 255, 255, 255, TEXT_CENTER, "HIGHSCORE: %03d", highscore);
if (points > highscore)
{
drawText(SCREEN_WIDTH / 2, 200, 255, 255, 255, TEXT_CENTER, "NEW HIGHSCORE: %03d", points, highscore);
}
}
}
}
void GameScene::update()
{
if (isGameOver == true)
{
if (app.keyboard[SDL_SCANCODE_SPACE])
{
isGameOver = false;
}
}
if (isGameOver == false)
{
Scene::update();
floorCollision();
obstacleCollision();
birdCollision();
if (currentSpawnTimer > 0)
currentSpawnTimer--;
if (currentSpawnTimer <= 0)
{
for (int i = 0; i < 1; i++)
{
obstacleSpawn();
}
for (int i = 0; i < 3; i++)
{
birdSpawn();
}
currentSpawnTimer = spawnTime;
}
//This is where Gravity strength is located
if (player->getOnFloor() == false) {
player->setY(player->getY() + 7);
}
else {
player->getY() + 0;
}
}
}
void GameScene::floorCollision()
{
//Checks for collisions
for (int i = 0; i < objects.size(); i++)
{
//Cast to floor
Floor* floor = dynamic_cast<Floor*>(objects[i]);
//Check if the floor was casted
if (floor != NULL)
{
int collision = checkCollision(
player->getX(), player->getY(), player->getWidth(), player->getHeight(),
floor->getX(), floor->getY(), floor->getWidth(), floor->getHeight()
);
if (collision == 1)
{
player->setOnFloor(true);
if (player->getIsAlive() == true)
{
points++;
highscore++;
}
break;
}
}
}
}
void GameScene::obstacleCollision()
{
for (int i = 0; i < objects.size(); i++)
{
Obstacle* obstacle = dynamic_cast<Obstacle*>(objects[i]);
if (obstacle != NULL)
{
if (obstacle != NULL)
{
int collision = checkCollision(
player->getX(), player->getY(), player->getWidth(), player->getHeight(),
obstacle->getX(), obstacle->getY(), obstacle->getWidth(), obstacle->getHeight()
);
if (collision == 1)
{
player->doDeath();
isGameOver = true;
break;
}
}
}
}
}
void GameScene::birdCollision()
{
for (int i = 0; i < objects.size(); i++)
{
FlyingObstacle* bird = dynamic_cast<FlyingObstacle*>(objects[i]);
if (bird != NULL)
{
if (bird != NULL)
{
int collision = checkCollision(
player->getX(), player->getY(), player->getWidth(), player->getHeight(),
bird->getX(), bird->getY(), bird->getWidth(), bird->getHeight()
);
if (collision == 1)
{
player->doDeath();
isGameOver = true;
break;
}
}
}
}
}
void GameScene::obstacleSpawn()
{
Obstacle* obstacle = new Obstacle();
this->addGameObject(obstacle);
obstacle->setPosition(1200, 300 + (rand() % 300));
spawnedObstacle.push_back(obstacle);
}
void GameScene::birdSpawn()
{
FlyingObstacle* bird = new FlyingObstacle();
this->addGameObject(bird);
bird->setPos(1200, 300 + (rand() % 300));
spawnedBird.push_back(bird);
}
void GameScene::despawnObstacle(Obstacle* obstacle)
{
int index = -1;
for (int i = 0; i < spawnedObstacle.size(); i++)
{
//If pointer matches
if (obstacle == spawnedObstacle[i])
{
index = i;
break;
}
}
//If any match is found
if (index != -1)
{
spawnedObstacle.erase(spawnedObstacle.begin() + index);
delete obstacle;
}
}
void GameScene::despawnBird(FlyingObstacle* bird)
{
int index = -1;
for (int i = 0; i < spawnedBird.size(); i++)
{
//If pointer matches
if (bird == spawnedBird[i])
{
index = i;
break;
}
}
//If any match is found
if (index != -1)
{
spawnedBird.erase(spawnedBird.begin() + index);
delete bird;
}
}
I tried making an isGameOver bool inside my GameScene.h and I made it so that pressing spacebar would reset the game but in reality when the player dies the screen pauses every movement instead of resetting and if I press space again the game continues to move even though the player is dead.
Your entry point for the game(probably main function will probably have some form like this)
#include ...
#include ...
...
int main()
{
bool game_running = true;
while(game_running)
{
GameInstance* game = new Game(); //Allocation and initialization of all resources needed to play the game.
game.play(); // This function will finish when you lose the game.
delete game; // Deallocation.
if(!run_again())
{
game_running = false;
}
}
return 0;
}
After deallocation, you check if user wants to play again, you enter the next iteration of while loop, and new instance of Game is allocated, where all the resource handling takes place. The only problem is that allocating Game instance for every iteration might be a little costly, but you can ignore that if you don't worry about performance much.

Allegro 5 Audio Assertion Fail

I'm wondering if anyone can point me in the right direction for this error.
I am learning 2D game programming using Allegro 5 installed in Visual Studio 2010.
I have been following a tutorial series and everything has been fine until the last lesson.
The final code will build successfully. The executable will load but will crash out when I hit the space bar to fire a bullet (it's a side shooter game). I get the following error:
"Assertion failed: spl, file allegro-git\addons\audio\kgm_sample.c line 321"
It obviously has something to do with the bullet sample sound linked in with the key press.
If I comment out the line: al_play_sample(shot, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0); in the FireBullet() function, then the game will play fine (without the bullet sound).
I have searched everywhere and cannot find a solution.
Here is the complete code for the game:
#include <allegro5\allegro.h>
#include <allegro5\allegro_primitives.h>
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_ttf.h>
#include <allegro5\allegro_image.h>
#include <allegro5\allegro_audio.h>
#include <allegro5\allegro_acodec.h>
#include "objects.h"
//GLOBALS==============================
const int WIDTH = 800;
const int HEIGHT = 400;
const int NUM_BULLETS = 5;
const int NUM_COMETS = 10;
const int NUM_EXPLOSIONS = 5;
enum STATE{TITLE, PLAYING, LOST};
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE};
bool keys[5] = {false, false, false, false, false};
SpaceShip ship;
Bullet bullets[NUM_BULLETS];
Comet comets[NUM_COMETS];
Explosion explosions[NUM_EXPLOSIONS];
ALLEGRO_SAMPLE *shot = NULL;
ALLEGRO_SAMPLE *boom = NULL;
ALLEGRO_SAMPLE *song = NULL;
ALLEGRO_SAMPLE_INSTANCE *songInstance = NULL;
//prototypes
void InitShip(SpaceShip &ship, ALLEGRO_BITMAP *image);
void ResetShipAnimation(SpaceShip &ship, int position);
void DrawShip(SpaceShip &ship);
void MoveShipUp(SpaceShip &ship);
void MoveShipDown(SpaceShip &ship);
void MoveShipLeft(SpaceShip &ship);
void MoveShipRight(SpaceShip &ship);
void InitBullet(Bullet bullet[], int size);
void DrawBullet(Bullet bullet[], int size);
void FireBullet(Bullet bullet[], int size, SpaceShip &ship);
void UpdateBullet(Bullet bullet[], int size);
void CollideBullet(Bullet bullet[], int bSize, Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize);
void InitComet(Comet comets[], int size, ALLEGRO_BITMAP *image);
void DrawComet(Comet comets[], int size);
void StartComet(Comet comets[], int size);
void UpdateComet(Comet comets[], int size);
void CollideComet(Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize);
void InitExplosions(Explosion explosions[], int size, ALLEGRO_BITMAP *image);
void DrawExplosions(Explosion explosions[], int size);
void StartExplosions(Explosion explosions[], int size, int x, int y);
void UpdateExplosions(Explosion explosions[], int size);
void InitBackground(Background &back, float x, float y, float velX, float velY, int width, int height, int dirX, int dirY, ALLEGRO_BITMAP *image);
void UpdateBackground(Background &back);
void DrawBackground(Background &back);
void ChangeState(int &state, int newState);
int main(void)
{
//primitive variable
bool done = false;
bool redraw = true;
const int FPS = 60;
int state = -1;
//object variables
Background BG;
Background MG;
Background FG;
//Allegro variables
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
ALLEGRO_FONT *font18 = NULL;
ALLEGRO_BITMAP *shipImage;
ALLEGRO_BITMAP *cometImage;
ALLEGRO_BITMAP *expImage;
ALLEGRO_BITMAP *title = NULL;
ALLEGRO_BITMAP *lost = NULL;
ALLEGRO_BITMAP *bgImage = NULL;
ALLEGRO_BITMAP *mgImage = NULL;
ALLEGRO_BITMAP *fgImage = NULL;
//Initialization Functions
if(!al_init()) //initialize Allegro
return -1;
display = al_create_display(WIDTH, HEIGHT); //create our display object
if(!display) //test display object
return -1;
al_init_primitives_addon();
al_install_keyboard();
al_init_font_addon();
al_init_ttf_addon();
al_init_image_addon();
al_install_audio();
al_init_acodec_addon();
event_queue = al_create_event_queue();
timer = al_create_timer(1.0 / FPS);
shipImage = al_load_bitmap("spaceship_by_arboris.png");
al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255));
cometImage = al_load_bitmap("asteroids.png");
expImage = al_load_bitmap("explosion.png");
title = al_load_bitmap("Shooter_Title.png");
lost = al_load_bitmap("Shooter_Lose.png");
bgImage = al_load_bitmap("starBG.png");
mgImage = al_load_bitmap("starMG.png");
fgImage = al_load_bitmap("starFG.png");
al_reserve_samples(10);
shot = al_load_sample("shot.ogg");
boom = al_load_sample("explosion.wav");
song = al_load_sample("war.wav");
songInstance = al_create_sample_instance(song);
al_set_sample_instance_playmode(songInstance, ALLEGRO_PLAYMODE_LOOP);
al_attach_sample_instance_to_mixer(songInstance, al_get_default_mixer());
srand(time(NULL));
ChangeState(state, TITLE);
InitShip(ship, shipImage);
InitBullet(bullets, NUM_BULLETS);
InitComet(comets, NUM_COMETS, cometImage);
InitExplosions(explosions, NUM_EXPLOSIONS, expImage);
InitBackground(BG, 0, 0, 1, 0, 800, 400, -1, 1, bgImage);
InitBackground(MG, 0, 0, 2, 0, 2400, 400, -1, 1, mgImage);
InitBackground(FG, 0, 0, 4, 0, 2400, 400, -1, 1, fgImage);
font18 = al_load_font("arial.ttf", 18, 0);
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_register_event_source(event_queue, al_get_display_event_source(display));
al_start_timer(timer);
while(!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if(ev.type == ALLEGRO_EVENT_TIMER)
{
redraw = true;
if(keys[UP])
MoveShipUp(ship);
else if(keys[DOWN])
MoveShipDown(ship);
else
ResetShipAnimation(ship, 1);
if(keys[LEFT])
MoveShipLeft(ship);
else if(keys[RIGHT])
MoveShipRight(ship);
else
ResetShipAnimation(ship, 2);
if(state == TITLE)
{}
else if(state == PLAYING)
{
UpdateBackground(BG);
UpdateBackground(MG);
UpdateBackground(FG);
UpdateExplosions(explosions, NUM_EXPLOSIONS);
UpdateBullet(bullets, NUM_BULLETS);
StartComet(comets, NUM_COMETS);
UpdateComet(comets, NUM_COMETS);
CollideBullet(bullets, NUM_BULLETS, comets, NUM_COMETS, ship, explosions, NUM_EXPLOSIONS);
CollideComet(comets, NUM_COMETS, ship, explosions, NUM_EXPLOSIONS);
if(ship.lives <= 0)
ChangeState(state, LOST);
}
else if(state == LOST)
{}
}
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
done = true;
}
else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_UP:
keys[UP] = true;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = true;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = true;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = true;
break;
case ALLEGRO_KEY_SPACE:
keys[SPACE] = true;
if(state == TITLE)
ChangeState(state, PLAYING);
else if(state ==PLAYING)
FireBullet(bullets, NUM_BULLETS, ship);
else if(state == LOST)
ChangeState(state, PLAYING);
break;
}
}
else if(ev.type == ALLEGRO_EVENT_KEY_UP)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_UP:
keys[UP] = false;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = false;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = false;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = false;
break;
case ALLEGRO_KEY_SPACE:
keys[SPACE] = false;
break;
}
}
if(redraw && al_is_event_queue_empty(event_queue))
{
redraw = false;
if(state == TITLE)
{
al_draw_bitmap(title, 0, 0, 0);
}
else if(state == PLAYING)
{
DrawBackground(BG);
DrawBackground(MG);
DrawBackground(FG);
DrawShip(ship);
DrawBullet(bullets, NUM_BULLETS);
DrawComet(comets, NUM_COMETS);
DrawExplosions(explosions, NUM_EXPLOSIONS);
al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Player has %i lives left. Player has destroyed %i objects", ship.lives, ship.score);
}
else if(state == LOST)
{
al_draw_bitmap(lost, 0, 0, 0);
al_draw_textf(font18, al_map_rgb(0, 255, 255), WIDTH - 10, 20, ALLEGRO_ALIGN_RIGHT, "Final Score: %i", ship.score);
}
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
}
}
al_destroy_sample(shot);
al_destroy_sample(boom);
al_destroy_sample(song);
al_destroy_sample_instance(songInstance);
al_destroy_bitmap(bgImage);
al_destroy_bitmap(mgImage);
al_destroy_bitmap(fgImage);
al_destroy_bitmap(title);
al_destroy_bitmap(lost);
al_destroy_bitmap(expImage);
al_destroy_bitmap(cometImage);
al_destroy_bitmap(shipImage);
al_destroy_event_queue(event_queue);
al_destroy_timer(timer);
al_destroy_font(font18);
al_destroy_display(display); //destroy our display object
return 0;
}
void InitShip(SpaceShip &ship, ALLEGRO_BITMAP *image = NULL) {
ship.x = 20;
ship.y = HEIGHT / 2;
ship.ID = PLAYER;
ship.lives = 3;
ship.speed = 6;
ship.boundx = 10;
ship.boundy = 12;
ship.score = 0;
ship.maxFrame = 3;
ship.curFrame = 0;
ship.frameCount = 0;
ship.frameDelay = 50;
ship.frameWidth = 44;
ship.frameHeight = 41;
ship.animationColumns = 3;
ship.animationDirection = 1;
ship.animationRow = 1;
if(image != NULL)
ship.image = image;
}
void ResetShipAnimation(SpaceShip &ship, int position)
{
if(position == 1)
ship.animationRow = 1;
else
ship.curFrame = 0;
}
void DrawShip(SpaceShip &ship)
{
int fx =(ship.curFrame % ship.animationColumns) * ship.frameWidth;
int fy = ship.animationRow * ship.frameHeight;
al_draw_bitmap_region(ship.image, fx, fy, ship.frameWidth,
ship.frameHeight, ship.x - ship.frameWidth / 2, ship.y - ship.frameHeight / 2, 0);
/*al_draw_filled_rectangle(ship.x - ship.boundx, ship.y - ship.boundy, ship.x + ship.boundx,
ship.y + ship.boundy, al_map_rgba(255, 0, 255, 100));*/
}
void MoveShipUp(SpaceShip &ship)
{
ship.animationRow = 0;
ship.y -= ship.speed;
if(ship.y < 0)
ship.y = 0;
}
void MoveShipDown(SpaceShip &ship)
{
ship.animationRow = 2;
ship.y += ship.speed;
if(ship.y > HEIGHT)
ship.y = HEIGHT;
}
void MoveShipLeft(SpaceShip &ship)
{
ship.curFrame = 2;
ship.x -= ship.speed;
if(ship.x < 0)
ship.x = 0;
}
void MoveShipRight(SpaceShip &ship)
{
ship.curFrame = 1;
ship.x += ship.speed;
if(ship.x > 300)
ship.x = 300;
}
void InitBullet(Bullet bullet[], int size)
{
for(int i = 0; i < size; i++)
{
bullet[i].ID = BULLET;
bullet[i].speed = 10;
bullet[i].live = false;
}
}
void DrawBullet(Bullet bullet[], int size)
{
for( int i = 0; i < size; i++)
{
if(bullet[i].live)
al_draw_filled_circle(bullet[i].x, bullet[i].y, 2, al_map_rgb(255, 255, 255));
}
}
void FireBullet(Bullet bullet[], int size, SpaceShip &ship)
{
for( int i = 0; i < size; i++)
{
if(!bullet[i].live)
{
bullet[i].x = ship.x + 17;
bullet[i].y = ship.y;
bullet[i].live = true;
al_play_sample(shot, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
break;
}
}
}
void UpdateBullet(Bullet bullet[], int size)
{
for(int i = 0; i < size; i++)
{
if(bullet[i].live)
{
bullet[i].x += bullet[i].speed;
if(bullet[i].x > WIDTH)
bullet[i].live = false;
}
}
}
void CollideBullet(Bullet bullet[], int bSize, Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize)
{
for(int i = 0; i < bSize; i++)
{
if(bullet[i].live)
{
for(int j =0; j < cSize; j++)
{
if(comets[j].live)
{
if(bullet[i].x > (comets[j].x - comets[j].boundx) &&
bullet[i].x < (comets[j].x + comets[j].boundx) &&
bullet[i].y > (comets[j].y - comets[j].boundy) &&
bullet[i].y < (comets[j].y + comets[j].boundy))
{
bullet[i].live = false;
comets[j].live = false;
ship.score++;
StartExplosions(explosions, eSize, bullet[i].x, bullet[i].y);
al_play_sample(boom, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
}
}
}
}
}
}
void InitComet(Comet comets[], int size, ALLEGRO_BITMAP *image = NULL)
{
for(int i = 0; i < size; i++)
{
comets[i].ID = ENEMY;
comets[i].live = false;
comets[i].speed = 5;
comets[i].boundx = 35;
comets[i].boundy = 35;
comets[i].maxFrame = 143;
comets[i].curFrame = 0;
comets[i].frameCount = 0;
comets[i].frameDelay = 2;
comets[i].frameWidth = 96;
comets[i].frameHeight = 96;
comets[i].animationColumns = 21;
if(rand() % 2)
comets[i].animationDirection = 1;
else
comets[i].animationDirection = -1;
if(image != NULL)
comets[i].image = image;
}
}
void DrawComet(Comet comets[], int size)
{
for(int i = 0; i < size; i++)
{
if(comets[i].live)
{
int fx = (comets[i].curFrame % comets[i].animationColumns) * comets[i].frameWidth;
int fy = (comets[i].curFrame / comets[i].animationColumns) * comets[i].frameHeight;
al_draw_bitmap_region(comets[i].image, fx, fy, comets[i].frameWidth,
comets[i].frameHeight, comets[i].x - comets[i].frameWidth / 2, comets[i].y - comets[i].frameHeight / 2, 0);
/*al_draw_filled_rectangle(comets[i].x - comets[i].boundx, comets[i].y - comets[i].boundy, comets[i].x + comets[i].boundx,
comets[i].y + comets[i].boundy, al_map_rgba(255, 0, 255, 100));*/
}
}
}
void StartComet(Comet comets[], int size)
{
for(int i = 0; i < size; i++)
{
if(!comets[i].live)
{
if(rand() % 500 == 0)
{
comets[i].live = true;
comets[i].x = WIDTH;
comets[i].y = 30 + rand() % (HEIGHT - 60);
break;
}
}
}
}
void UpdateComet(Comet comets[], int size)
{
for(int i = 0; i < size; i++)
{
if(comets[i].live)
{
if(++comets[i].frameCount >= comets[i].frameDelay)
{
comets[i].curFrame += comets[i].animationDirection;
if(comets[i].curFrame >= comets[i].maxFrame)
comets[i].curFrame = 0;
else if( comets[i].curFrame <= 0)
comets[i].curFrame = comets[i].maxFrame - 1;
comets[i].frameCount = 0;
}
comets[i].x -= comets[i].speed;
}
}
}
void CollideComet(Comet comets[], int cSize, SpaceShip &ship, Explosion explosions[], int eSize)
{
for(int i = 0; i < cSize; i++)
{
if(comets[i].live)
{
if(comets[i].x - comets[i].boundx < ship.x + ship.boundx &&
comets[i].x + comets[i].boundx > ship.x - ship.boundx &&
comets[i].y - comets[i].boundy < ship.y + ship.boundy &&
comets[i].y + comets[i].boundy > ship.y - ship.boundy)
{
ship.lives--;
comets[i].live = false;
StartExplosions(explosions, eSize, ship.x, ship.y);
al_play_sample(boom, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);
}
else if(comets[i].x < 0)
{
comets[i].live = false;
ship.lives--;
}
}
}
}
void InitExplosions(Explosion explosions[], int size, ALLEGRO_BITMAP *image = NULL)
{
for(int i = 0; i < size; i++)
{
explosions[i].live = false;
explosions[i].maxFrame = 31;
explosions[i].curFrame = 0;
explosions[i].frameCount = 0;
explosions[i].frameDelay = 1;
explosions[i].frameWidth = 128;
explosions[i].frameHeight = 128;
explosions[i].animationColumns = 8;
explosions[i].animationDirection = 1;
if(image != NULL)
explosions[i].image = image;
}
}
void DrawExplosions(Explosion explosions[], int size)
{
for(int i = 0; i < size; i++)
{
if(explosions[i].live)
{
int fx = (explosions[i].curFrame % explosions[i].animationColumns) * explosions[i].frameWidth;
int fy = (explosions[i].curFrame / explosions[i].animationColumns) * explosions[i].frameHeight;
al_draw_bitmap_region(explosions[i].image, fx, fy, explosions[i].frameWidth,
explosions[i].frameHeight, explosions[i].x - explosions[i].frameWidth / 2, explosions[i].y - explosions[i].frameHeight / 2, 0);
}
}
}
void StartExplosions(Explosion explosions[], int size, int x, int y)
{
for(int i = 0; i < size; i++)
{
if(!explosions[i].live)
{
explosions[i].live = true;
explosions[i].x = x;
explosions[i].y = y;
break;
}
}
}
void UpdateExplosions(Explosion explosions[], int size)
{
for(int i = 0; i < size; i++)
{
if(explosions[i].live)
{
if(++explosions[i].frameCount >= explosions[i].frameDelay)
{
explosions[i].curFrame += explosions[i].animationDirection;
if(explosions[i].curFrame >= explosions[i].maxFrame)
{
explosions[i].curFrame = 0;
explosions[i].live = false;
}
explosions[i].frameCount = 0;
}
}
}
}
void InitBackground(Background &back, float x, float y, float velx, float vely, int width, int height, int dirX, int dirY, ALLEGRO_BITMAP *image)
{
back.x = x;
back.y = y;
back.velX = velx;
back.velY = vely;
back.width = width;
back.height = height;
back.dirX = dirX;
back.dirY = dirY;
back.image = image;
}
void UpdateBackground(Background &back)
{
back.x += back.velX * back.dirX;
if(back.x + back.width <= 0)
back.x = 0;
}
void DrawBackground(Background &back)
{
al_draw_bitmap(back.image, back.x, back.y, 0);
if(back.x + back.width < WIDTH)
al_draw_bitmap(back.image, back.x + back.width, back.y, 0);
}
void ChangeState(int &state, int newState)
{
if(state == TITLE)
{}
else if(state == PLAYING)
{
al_stop_sample_instance(songInstance);
}
else if(state == LOST)
{}
state = newState;
if(state == TITLE)
{}
else if(state == PLAYING)
{
InitShip(ship);
InitBullet(bullets, NUM_BULLETS);
InitComet(comets, NUM_COMETS);
InitExplosions(explosions, NUM_EXPLOSIONS);
al_play_sample_instance(songInstance);
}
else if(state == LOST)
{}
}
Check that a pointer you are using is not NULL when you try to load the file. If it stays NULL then that exception is always thrown because the system will try to read from memory address 0x0 which frankly does not exist

Clipboard operation in Graphics View

I have different subclasses for my entities. The entities are drawn in GraphicsView, How can apply the Clipboard operations for Cut, Copy and Paste.
gEntity.h
#ifndef GENTITY_H
#define GENTITY_H
class gEntity :public QObject
{
public:
gEntity(QObject* parent=0) : QObject(parent) {}
virtual ~gEntity() {}
virtual gEntity* my_clone() { return 0; }
};
#endif // GENTITY_H
circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include <QPainter>
#include <QGraphicsItem>
#include <gentity.h>
#include "qmath.h"
class Circle : public QObject, public QGraphicsItem, public gEntity
{
Q_OBJECT
public:
Circle(QObject* parent=0) : gEntity(parent){
}
Circle(int, QPointF, QPointF);
Circle(int, QPointF, qreal);
QRectF boundingRect() const;
virtual void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget);
enum { Type = UserType + 3 };
int type() const;
int id;
QPointF center_p, end_p, move_p;
qreal radius;
void setRadius((const qreal &radius);
private:
QVector<QPointF> stuff;
};
#endif // CIRCLE_H
circle.cpp
#include "circle.h"
#include "gentity.h"
Circle::Circle(int i, QPointF p1, QPointF p2)
{
// assigns id
id = i;
/* set values of center point, end point
and calculate radius of circle */
center_p = p1;
end_p = p2;
radius = qSqrt(qPow((end_p.x()-center_p.x()), 2)
+ qPow((end_p.y()-center_p.y()), 2));
}
Circle::Circle(int i, QPointF p1, qreal rad)
{
// assigns id
id = i;
/* set values of center point
and radius of circle */
center_p = p1;
radius = rad;
}
int Circle::type() const
{
// Enable the use of qgraphicsitem_cast with circle item.
return Type;
}
QRectF Circle::boundingRect() const
{
// bounding rectangle for circle
return QRectF((center_p.x()-radius), (center_p.y()-radius),
(2*radius), (2*radius));
}
void Circle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
// draws/paints the path of circle
QPen paintpen(Qt::black);
paintpen.setWidth(1);
painter->setRenderHint(QPainter::Antialiasing);
if (isSelected())
{
// sets brush for center point
painter->setBrush(Qt::SolidPattern);
paintpen.setColor(Qt::red);
painter->setPen(paintpen);
painter->drawEllipse(center_p, 2, 2);
// sets pen for circumference
paintpen.setStyle(Qt::DashLine);
paintpen.setColor(Qt::black);
painter->setBrush(Qt::NoBrush);
painter->setPen(paintpen);
painter->drawEllipse(center_p, radius, radius);
}
else
{ painter->save();
painter->setBrush(Qt::SolidPattern);
paintpen.setColor(Qt::black);
painter->setPen(paintpen);
painter->drawEllipse(center_p, 2, 2);
painter->setBrush(Qt::NoBrush);
painter->drawEllipse(center_p, radius, radius);
painter->restore();
}
}
gEntity* my_clone(){
Circle *c = new Circle();
c->setRadius(radius);
return c;
}
Clipboard.h
#include<QStack>
#include<QClipboard>
class MyClipBoard
{
public:
static MyClipBoard* instance()
{
if(!inst)
inst = new MyClipBoard;
return inst;
}
void push(gEntity* g) {
clips.push(g);
}
gEntity* last()
{
if(clips.count() == 0) return 0;
return clips.last();
}
gEntity* pop()
{
if(clips.count() == 0) return 0;
return clips.pop();
}
bool isempty() const { return clips.empty(); }
private:
QStack<gEntity*> clips;
static MyClipBoard* inst;
};
CadgraphicsScene.cpp
MyClipBoard* MyClipBoard::inst = 0;
CadGraphicsScene::CadGraphicsScene(QObject *parent, QUndoStack *undoStack)
: QGraphicsScene(parent)
{
setFlags();
id = 0;
mUndoStack = undoStack;
m_context = new QMenu;
m_context->addAction("Insert Circle");
a_cut = m_context->addAction("cut");
a_copy = m_context->addAction("copy");
a_paste = m_context->addAction("paste");
context_item = 0;
connect(m_context, SIGNAL(triggered(QAction*)), this, SLOT(contmenu(QAction*)));
}
void CadGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
m_context->exec(event->screenPos());
}
void CadGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
// mousePressEvent in the graphicsScene
if(mouseEvent->button() == Qt::LeftButton)
{
switch (entityMode)
{
case NoMode:
qDebug() << "No Mode";
break;
case PointMode:
pointItem = new Point(++id);
pointItem->setPos(mouseEvent->scenePos());
itemList.append(pointItem);
mUndoStack->push(new CadCommandAdd(this, pointItem));
break;
case LineMode:
if (mFirstClick)
{
start_p = mouseEvent->scenePos();
mFirstClick = false;
mSecondClick = true;
}
else if (!mFirstClick && mSecondClick)
{
end_p = mouseEvent->scenePos();
mPaintFlag = true;
mSecondClick = false;
}
if (mPaintFlag)
{
lineItem = new Line(++id, start_p, end_p);
lineItem->setLine(start_p.x(), start_p.y(), end_p.x(), end_p.y());
itemList.append(lineItem);
mUndoStack->push(new CadCommandAdd(this, lineItem));
setFlags();
}
break;
case CircleMode:
if (mFirstClick)
{
start_p = mouseEvent->scenePos();
mFirstClick = false;
mSecondClick = true;
}
else if (!mFirstClick && mSecondClick)
{
end_p = mouseEvent->scenePos();
mPaintFlag = true;
mSecondClick = false;
}
if (mPaintFlag)
{
circleItem = new Circle(++id, start_p, end_p);
itemList.append(circleItem);
mUndoStack->push(new CadCommandAdd(this, circleItem));
setFlags();
}
break;
case EllipseMode:
if (mFirstClick)
{
start_p = mouseEvent->scenePos();
mFirstClick = false;
mSecondClick = true;
}
else if (!mFirstClick && mSecondClick)
{
mid_p = mouseEvent->scenePos();
mFirstClick = false;
mSecondClick = false;
mThirdClick = true;
}
else if (!mSecondClick && mThirdClick)
{
end_p = mouseEvent->scenePos();
mThirdClick = false;
mPaintFlag = true;
}
if (mPaintFlag)
{
ellipseItem = new Ellipse(++id, start_p, mid_p, end_p);
itemList.append(ellipseItem);
mUndoStack->push(new CadCommandAdd(this, ellipseItem));
setFlags();
}
break;
case TextMode:
textItem = new mText(++id);
textItem->setPos(mouseEvent->scenePos());
itemList.append(textItem);
textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
mUndoStack->push(new CadCommandAdd(this, textItem));
connect(textItem, SIGNAL(lostFocus(mText*)),
this, SLOT(editorLostFocus(mText*)));
connect(textItem, SIGNAL(selectedChange(QGraphicsItem*)),
this, SIGNAL(itemSelected(QGraphicsItem*)));
setFlags();
default:
;
}
}else if(event->button() & Qt::RightButton)
{
context_item = itemAt(event->scenePos().toPoint(), QTransform());//base operand not a pointer
cpos = event->scenePos();//says invalid use of member function
if(!context_item)//Here it says all variables out of scope
{
a_cut->setEnabled(false);
a_copy->setEnabled(false);
if(MyClipBoard::instance()->isempty())
a_paste->setEnabled(false);
else a_paste->setEnabled(true);
}
else
{
a_cut->setEnabled(true);
a_copy->setEnabled(true);
a_paste->setEnabled(false);
}
}
QGraphicsScene::mousePressEvent(mouseEvent);
}
cadgraphicsscene.h
private:
QMenu* m_context;
QAction* a_cut;
QAction* a_copy;
QAction* a_paste;
QGraphicsItem* context_item;
QPointF cpos;
what are you mean of cutting a grahicsitem? (change its position or move to another view)
for copy and paste search for cloning a object in c++ it's not hard, and in paste just change position of new object and add that to your graphicsview or scene
update:
#ifndef MYSCENE_H
#define MYSCENE_H
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsSceneContextMenuEvent>
#include <QMenu>
#include <QStack>
class gEntity : public QObject, public QGraphicsItem
{
public:
gEntity(QObject* parent=0) : QObject(parent) {}
virtual ~gEntity() {}
virtual gEntity* my_clone() { return 0; }
};
class Circle : public gEntity
{
public:
Circle(QObject* parent=0) : gEntity(parent) {
m_radius = 10;
}
qreal radius() const;
void setRadius(const qreal &radius);
gEntity* my_clone()
{
Circle* c = new Circle;
c->setRadius(m_radius);
return c;
}
QRectF boundingRect() const
{
return QRectF(-m_radius, -m_radius, 2 * m_radius, 2 * m_radius);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->save();
painter->setBrush(Qt::yellow);
painter->drawEllipse(QPointF(0,0), m_radius, m_radius);
painter->restore();
}
private:
qreal m_radius;
};
class MyClipBoard
{
public:
static MyClipBoard* instance()
{
if(!inst)
inst = new MyClipBoard;
return inst;
}
void push(gEntity* g) {
clips.push(g);
}
gEntity* last()
{
if(clips.count() == 0) return 0;
return clips.last();
}
gEntity* pop()
{
if(clips.count() == 0) return 0;
return clips.pop();
}
bool isempty() const { return clips.empty(); }
private:
QStack<gEntity*> clips;
static MyClipBoard* inst;
};
class MyScene : public QGraphicsScene
{
Q_OBJECT
public:
MyScene(QObject* parent=0);
virtual ~MyScene()
{
delete m_context;
}
protected:
void contextMenuEvent(QGraphicsSceneContextMenuEvent* event);
void mousePressEvent(QGraphicsSceneMouseEvent* event);
public slots:
void insertCircle(const QPointF& pos)
{
Circle* mcircle = new Circle;
addItem(mcircle);
mcircle->setPos(pos);
}
void cut(gEntity* obj)
{
removeItem(obj);
MyClipBoard::instance()->push(obj);
}
void copy(gEntity* obj)
{
MyClipBoard::instance()->push(obj->my_clone());
}
void paste(const QPointF& pos)
{
gEntity* last = MyClipBoard::instance()->pop();
if(last)
{
addItem(last);
last->setPos(pos);
}
}
void contmenu(QAction* a)
{
if(a->text() == "Insert Circle")
{
insertCircle(cpos);
}
else if(a == a_cut)
{
cut(static_cast<gEntity*>(context_item));
}
else if(a == a_copy)
{
copy(static_cast<gEntity*>(context_item));
}
else if(a == a_paste)
{
paste(cpos);
}
}
private:
QMenu* m_context;
QAction* a_cut;
QAction* a_copy;
QAction* a_paste;
QGraphicsItem* context_item;
QPointF cpos;
};
#endif // MYSCENE_H
scene.cpp
#include "myscene.h"
#include <QGraphicsSceneMouseEvent>
MyClipBoard* MyClipBoard::inst = 0;
qreal Circle::radius() const
{
return m_radius;
}
void Circle::setRadius(const qreal &radius)
{
m_radius = radius;
}
MyScene::MyScene(QObject *parent) : QGraphicsScene(parent)
{
m_context = new QMenu;
m_context->addAction("Insert Circle");
a_cut = m_context->addAction("cut");
a_copy = m_context->addAction("copy");
a_paste = m_context->addAction("paste");
context_item = 0;
connect(m_context, SIGNAL(triggered(QAction*)), this, SLOT(contmenu(QAction*)));
}
void MyScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){
m_context->exec(event->screenPos());
}
void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsScene::mousePressEvent(event);
if(event->button() & Qt::RightButton)
{
context_item = itemAt(event->scenePos().toPoint(), QTransform());
cpos = event->scenePos();
if(!context_item)
{
a_cut->setEnabled(false);
a_copy->setEnabled(false);
if(MyClipBoard::instance()->isempty())
a_paste->setEnabled(false);
else a_paste->setEnabled(true);
}
else
{
a_cut->setEnabled(true);
a_copy->setEnabled(true);
a_paste->setEnabled(false);
}
}
}
main.cpp
#include <QApplication>
#include "myscene.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsView w(new MyScene);
w.setSceneRect(0,0,500,500);
w.show();
return a.exec();
}

Bug in Button class - Windows triggered a breakpoint SDL

I am a novice C++ programmer, and I have been experimenting with the SDL libraries for 2d graphics. I have been messing around with try to create some simple GUI controls; however, my button control is having a weird issue that I have been unable to resolve.
Whenever I launch the program in debug mode Visual Studio immediately gives me an error window saying
"Windows has triggered a breakpoint in Default_SDL_Setup.exe.
This may be due to a corruption of the heap, which indicates a bug in
Default_SDL_Setup.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while
Default_SDL_Setup.exe has focus.
The output window may have more diagnostic information."
and pops up a file called crtexe.c in the code editor window.
I have no idea what is wrong or what is going on.
Here is my button header:
#ifndef BUTTON_T
#define BUTTON_T
#include <vector>
#include <string>
#include "SDL.h"
#include "SDL_ttf.h"
#include "SDLFunctions.h"
#endif
class button
{
private:
//refreshes the button
void refresh_image();
bool refresh;
//surface to hold the created text
SDL_Surface *message;
//color of text
SDL_Color tC;
//the different box types
struct boxColor
{
unsigned int r;
unsigned int g;
unsigned int b;
};
boxColor boxes[4];
SDL_Rect rects[4];
//font of text
TTF_Font *f;
/*button's state
* States are:
* 0 - mouseout
* 1 - mouseover
* 2 - mousedown
* 3 - mouseup
*/
int state;
public:
//autosize based off of text?
bool autoSize;
//size of text
int textSize;
//x,y,w,and h for the box
int x, y, w, h;
//text of the label
std::string text;
button(int xpos, int ypos, int width, int height);
~button();
//handles all events for the button
void handleEvents(SDL_Event *event);
//sets text's font style off of a string location, color expects a 3 dimensional array
void setFont(std::string fontFileLocation);
void setFont(int color[3]);
void setFont(std::string fontFileLocation, int color[3]);
//gets the text color as a vector
std::vector<int> textColor();
//returns the color of the specified box
std::vector<int> boxColor(int boxnum);
//sets the color of the specified box, expects a 3 dimensional array
void setBoxColor(int boxnum, int color[3]);
void render(SDL_Surface *screen);
};
Here is the button code:
#include "button.h"
using namespace std;
void button::refresh_image()
{
if (refresh)
{
if (f != NULL)
{
message = TTF_RenderText_Solid(f, text.c_str(), tC);
if ((message != NULL) && autoSize)
{
if (message->w >= w)
{
w = (message->w + 10);
}
if (message->h >= h)
{
h = (message->h + 10);
}
}
}
for (int i = 0; i != 4; ++i)
{
rects[i].x = x;
rects[i].y = y;
rects[i].w = w;
rects[i].h = h;
}
refresh = false;
}
}
button::button(int xpos, int ypos, int width, int height)
{
string defaultFontLocation = DEFAULT_FONT;
//set pos
x = xpos;
y = ypos;
w = width;
h = height;
//set text stuff
text = "";
textSize = DEFAULT_FONT_SIZE;
tC.r = 0;
tC.g = 0;
tC.b = 0;
f = TTF_OpenFont(defaultFontLocation.c_str(), textSize);
message = NULL;
//create box types
state = 0;
for (int i = 0; i != 4; ++i)
{
boxes[i].r = 255;
boxes[i].g = 255;
boxes[i].b = 255;
rects[i].x = x;
rects[i].y = y;
rects[i].w = w;
rects[i].h = h;
}
autoSize = true;
refresh = true;
refresh_image();
}
button::~button()
{
if (f != NULL)
{
TTF_CloseFont(f);
}
if (message != NULL)
{
SDL_FreeSurface(message);
}
}
void button::setFont(string fontFileLocation)
{
if (f != NULL)
{
TTF_CloseFont(f);
}
f = TTF_OpenFont(fontFileLocation.c_str(), textSize);
refresh_image();
}
void button::setFont(int color[3])
{
tC.r = color[0];
tC.g = color[1];
tC.b = color[2];
refresh_image();
}
void button::setFont(string fontFileLocation, int color[3])
{
if (f != NULL)
{
TTF_CloseFont(f);
}
f = TTF_OpenFont(fontFileLocation.c_str(), textSize);
tC.r = color[0];
tC.g = color[1];
tC.b = color[2];
refresh_image();
}
vector<int> button::textColor()
{
vector<int> colors;
colors.resize(3);
colors[0] = tC.r;
colors[1] = tC.g;
colors[2] = tC.b;
return colors;
}
vector<int> button::boxColor(int boxnum)
{
vector<int> colors;
colors.resize(3);
if ((boxnum <= 3) && (boxnum >= 0))
{
colors[0] = boxes[boxnum].r;
colors[1] = boxes[boxnum].g;
colors[2] = boxes[boxnum].b;
} else {
colors[0] = -1;
colors[1] = -1;
colors[2] = -1;
}
return colors;
}
void button::setBoxColor(int boxnum, int color[3])
{
if ((boxnum <= 3) && (boxnum >= 0))
{
boxes[boxnum].r = color[0];
boxes[boxnum].g = color[1];
boxes[boxnum].b = color[2];
//refresh_image();
}
}
void button::render(SDL_Surface *screen)
{
refresh_image();
SDL_FillRect(screen, &rects[state], SDL_MapRGB(screen->format, static_cast<Uint8>(boxes[state].r), static_cast<Uint8>(boxes[state].g), static_cast<Uint8>(boxes[state].b)));
if (message != NULL)
{
apply_surface((((x + w) - message->w) / 2), (((y + h) - message->h) / 2), message, screen);
}
refresh = true;
}
void button::handleEvents(SDL_Event *event)
{
//the mouse offsets
int mx, my;
//if mouse moved
if (event->type == SDL_MOUSEMOTION)
{
//get the mouse offsets
mx = event->motion.x;
my = event->motion.y;
//if the mouse is over the button
if ((mx > x) && (mx < (x + w)) && (my > y) && (my < (y + h)))
{
//set the button sprite
state = 1;
} else {
//set the button sprite
state = 0;
}
}
//if a mouse button was pressed
if (event->type == SDL_MOUSEBUTTONDOWN)
{
//if it was the left mouse button
if (event->button.button == SDL_BUTTON_LEFT)
{
//get the mouse offsets
mx = event->motion.x;
my = event->motion.y;
//if the mouse is over the button
if ((mx > x) && (mx < (x + w)) && (my > y) && (my < (y + h)))
{
//set the button sprite
state = 2;
}
}
}
//if a mouse button was released
if (event->type == SDL_MOUSEBUTTONUP)
{
//if it was the left mouse button
if (event->button.button == SDL_BUTTON_LEFT)
{
//get the mouse offsets
mx = event->motion.x;
my = event->motion.y;
//if the mouse is over the button
if ((mx > x) && (mx < (x + w)) && (my > y) && (my < (y + h)))
{
//set the button sprite
state = 3;
}
}
}
}
and here is the code I have been calling to create the button in my main() function:
int color1[3] = {105,240,81};
int color2[3] = {230,188,62};
button testbutton(360, 130, 50, 30);
testbutton.text = "TEST";
testbutton.setBoxColor(1, color1);
testbutton.setBoxColor(2, color2);
delete[] &color1;
delete[] &color2;
The problem is most probably in these two lines:
delete[] &color1;
delete[] &color2;
color1 and color2are automatic variables, and calling delete on them invokes undefined behavior. You should only delete variables you previously allocated with new.

Form Glass Pane in LWUIT

I'm trying to make a waiting screen using Form Glass Pane in LWUIT, the following is the code that I'm using
public class LoadingGlassPane implements Painter {
public static boolean isShown = false;
public static IForm form;
public void paint(Graphics g, Rectangle rect) {
System.out.println("paint LoadingGlassPane");
Font font = g.getFont();
int color = g.getColor();
g.setColor(0);
g.setFont(Font.getDefaultFont());
g.drawString("Loading...", 20, 120);
g.setColor(color);
g.setFont(font);
}
public void installPane(IForm f) {
f.setGlassPane(this);
}
public void uninstallPane(IForm f) {
f.setGlassPane(null);
}
public static IForm getForm() {
return form;
}
public static void setForm(IForm form) {
LoadingGlassPane.form = form;
}
public static boolean isIsShown() {
return isShown;
}
public static void setIsShown(boolean isShown) {
LoadingGlassPane.isShown = isShown;
}
}
and
public class ProgressGlassPane extends LoadingGlassPane implements Animation, Runnable {
int spacing = 20;
int fontSpacing = 10;
String loadMsg = "Loading...";
//HTMLComponent htmlC;
// Dialog loading;
// public ProgressGlassPane(Dialog loading) {
// this.loading = loading;
// }
public ProgressGlassPane() {
}
public void paint(Graphics g, Rectangle rect) {
//while (isShown == true) {
System.out.println("paint ProgressGlassPane");
int color = g.getColor();
Font font = g.getFont();
int pos = (int) ((System.currentTimeMillis() % 2700) / 300);
Font f = Font.getDefaultFont();
//int startX = loading.getAbsoluteX() + (loading.getWidth() / 2) - spacing;
int startX = (LGB.width / 2) - spacing;
//int fontStartX = loading.getAbsoluteX() + (loading.getWidth() - f.stringWidth(loadMsg)) / 2;
int fontStartX = (LGB.width - f.stringWidth(loadMsg)) / 2;
//int startY = loading.getAbsoluteY() + (loading.getHeight() / 2) - spacing - (f.getHeight() + fontSpacing) / 2;
int startY = (LGB.height / 2) - spacing - (f.getHeight() + fontSpacing) / 2;
int i = 0;
g.setColor(0xffffff);
g.fillRect(Math.min(startX - 3, fontStartX), startY - 3, Math.max(spacing * 2 + 7, f.stringWidth(loadMsg)) + 1, spacing * 2 + 7 + f.getHeight() + fontSpacing);
g.setColor(0);
g.setFont(f);
g.drawString(loadMsg, fontStartX, startY);
startY += f.getHeight() + fontSpacing;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
int thickness = 3;
if (i == pos) {
thickness = 7;
} else if (i == pos - 1) {
thickness = 5;
}
g.fillRect(startX + x * spacing - (thickness / 2), startY + y * spacing - (thickness / 2), thickness, thickness);
i++;
}
}
g.setColor(color);
g.setFont(font);
// }
}
public boolean animate() {
return true;
}
public void paint(Graphics g) {
paint(g, null);
}
//void installPane(Form f) {
public void installPane(IForm f) {
super.installPane(f);
//f.setGlassPane(this);
f.registerAnimated(this);
}
//void uninstallPane(Form f) {
public void uninstallPane(IForm f) {
super.uninstallPane(f);
//f.setGlassPane(this);
f.deregisterAnimated(this);
}
public void run() {
System.out.println("I'm running");
if (isShown == true && form != null) {
installPane(form);
}
else
{
uninstallPane(form);
}
}
}
and from within my form
public static ProgressGlassPane progressPane;
progressPane = new ProgressGlassPane();
progressPane.setForm(this);
progressPane.setIsShown(true);
progressPane.run();
//Some Webservice code I want to run
progressPane.setIsShown(false);
What I want to do exactly is to open the glass pan while I'm loading my data and hide it when I finish, but what Happen it send the request and after get the response show the glass pane , I have tried to put my glass pane in different thread to run independently from the main thread, and it is also not working.
Is the webservice code blocking?
If you are on the EDT then that just wouldn't work. You need to uninstall from the completion.