Seite 1 von 1

enum in Qt nicht mit int-Werten ansprechbar??

Verfasst: 17. Juli 2011 16:34
von Morlockk
Hallo!

Ich habe ein problem bei der Deserialisierung von Werten in Qt. Es hat den Anschein, als ob man die Werte einer enum in Qt nicht mit den entsprechenden int-Werten ansprechen kann. Normal sollte das in c++ ja kein Problem sein...
Wenn ich auf diese Weise Daten laden will (ja, ich weiß. das code ist im Moment sicher noch alles andere als Perfekt.), dann bekomme ich folgende Fehlermeldung:

Fehler:invalid conversion from 'int' to 'zeichenFeld::drawType'

Dabei ist zeicheFeld::drawType eine enum und hinter einer enum steckt doch nichts anderes als int-Wert?!

Hier mal mein Code... Das laden der Koordinaten des beweglichen roten Kreises klappt wunderbar. Nur die grünen Quadrate und Kreise lädt er leider noch überhaupt nicht :-/
Der Fehler bezieht sich auf den letzten Codeblock, relativ am Ende in der Funktion deserialize. Wäre super wenn man mir hier weiterhelfen kann!

Code: Alles auswählen

#include "zeichenFeld.h"

class meinWidget : public QWidget
{
Q_OBJECT
public:
    meinWidget(QWidget *parent = 0);

private:
    zeichenFeld *meinZeichenFeld;


private slots:
    void square(void);
        void circle(void);
            void start(void);
                void stop(void);
                    void save(void);
                        void load(void);
};

Code: Alles auswählen

#include <vector>
using namespace std;
#include <QWidget>
#include <QTimer>
#include <QFile>


class zeichenFeld : public QWidget
{
public:
    zeichenFeld(QWidget *parent = 0);
    ~zeichenFeld();

    enum drawType {square, circle};
    void placeObject(enum drawType useType);
    void serialize(QFile &file);
    void deserialize(QFile &file);


    int moveX;
    int moveY;
    void start(void) { timer->start(10); increment=1; };
    void stop(void) { timer->stop(); increment=0; };


private:
    vector<struct myDrawingObject *> objects;
    QTimer *timer;
    int phase;
    int increment;
        int lastX;
        int lastY;


protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent( QMouseEvent* event);
};

struct myDrawingObject
   {
   zeichenFeld::drawType type;
   int x;
   int y;
   } ;

Code: Alles auswählen

#include <QtGui>
#include "meinWidget.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
meinWidget widget;
widget.setGeometry(100, 100, 800, 555);
widget.show();
return app.exec();
}

Code: Alles auswählen

#include <QtGui>
#include "meinWidget.h"

meinWidget::meinWidget(QWidget *parent)
     : QWidget(parent)
{
QPushButton *quit = new QPushButton(tr("Ende"));
quit->setFont(QFont("Times", 18, QFont::Bold));
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));

QPushButton *circleButton = new QPushButton(tr("Kreis"));
circleButton->setFont(QFont("Times", 18, QFont::Bold));
connect(circleButton, SIGNAL(clicked()), this, SLOT(circle()));

QPushButton *squareButton = new QPushButton(tr("Quadrat"));
squareButton->setFont(QFont("Times", 18, QFont::Bold));
connect(squareButton, SIGNAL(clicked()), this, SLOT(square()));

QPushButton *startButton = new QPushButton(tr("Start"));
startButton->setFont(QFont("Times", 18, QFont::Bold));
connect(startButton, SIGNAL(clicked()), this, SLOT(start()));

QPushButton *stopButton = new QPushButton(tr("Stop"));
stopButton->setFont(QFont("Times", 18, QFont::Bold));
connect(stopButton, SIGNAL(clicked()), this, SLOT(stop()));

QPushButton *saveButton = new QPushButton(tr("Speichern"));
saveButton->setFont(QFont("Times", 18, QFont::Bold));
connect(saveButton, SIGNAL(clicked()), this, SLOT(save()));

QPushButton *loadButton = new QPushButton(tr("Laden"));
loadButton->setFont(QFont("Times", 18, QFont::Bold));
connect(loadButton, SIGNAL(clicked()), this, SLOT(load()));


meinZeichenFeld = new zeichenFeld;

QGridLayout *gridLayout = new QGridLayout;
gridLayout->addWidget(quit, 0, 0);
gridLayout->addWidget(circleButton, 1, 0);
gridLayout->addWidget(squareButton, 2, 0);
gridLayout->addWidget(startButton, 3, 0);
gridLayout->addWidget(stopButton, 4, 0);
gridLayout->addWidget(saveButton, 5, 0);
gridLayout->addWidget(loadButton, 6, 0);
gridLayout->addWidget(meinZeichenFeld, 0, 1, 7, 1);
gridLayout->setColumnStretch(1, 10);
setLayout(gridLayout);
}

void meinWidget::circle(void)
{
        meinZeichenFeld->placeObject(zeichenFeld::circle);
}

void meinWidget::square(void)
{
        meinZeichenFeld->placeObject(zeichenFeld::square);
}

void meinWidget::start(void)
{
        meinZeichenFeld->start();
}

void meinWidget::stop(void)
{
        meinZeichenFeld->stop();
}

void meinWidget::save(void)
{
    QFileDialog dialog(this);
    QString fileName;
    QFile file;

    dialog.setFileMode(QFileDialog::AnyFile);
    fileName = dialog.getSaveFileName(this,
         tr("Speichern als"), ".", tr("Zeichnungen (*.myz)"));

    if (fileName.isNull()==false)
       {
       file.setFileName(fileName);
       if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
          {
          QMessageBox::warning(this, tr("Dateifehler"),
                       tr("Folgende Datei kann nicht verwendet werden: ") + fileName,QMessageBox::Ok);
          }

       meinZeichenFeld->serialize(file);
       file.close();
       return;
       }
}

void meinWidget::load(void)
{
    QFileDialog dialog(this);
    QString fileName;
    QFile file;

    dialog.setFileMode(QFileDialog::AnyFile);
    fileName = dialog.getOpenFileName(this,
         tr("Speichern als"), ".", tr("Zeichnungen (*.myz)"));

    if (fileName.isNull()==false)
       {
       file.setFileName(fileName);
       if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
          {
          QMessageBox::warning(this, tr("Dateifehler"),
                       tr("Folgende Datei kann nicht geöffnet werden: ") + fileName,QMessageBox::Ok);
          }

       meinZeichenFeld->deserialize(file);
       file.close();
       return;
       }
}

Code: Alles auswählen

#include <QtGui>
#include <math.h>
#include "zeichenFeld.h"


zeichenFeld::zeichenFeld(QWidget *parent)
     : QWidget(parent)
{
setPalette(QPalette(QColor(250, 250, 200)));
setAutoFillBackground(true);
setMouseTracking(false);

increment=0;
phase=0;
moveX=100;
moveY=100;

timer=new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
}



zeichenFeld::~zeichenFeld()
{
for (vector<struct myDrawingObject *>::iterator pos=objects.begin();pos!=objects.end();pos++)
    delete *pos;
}

void zeichenFeld::paintEvent(QPaintEvent * )
{
QPainter painter;
vector<struct myDrawingObject *>::iterator pos;
int x,y;

painter.begin(this);

painter.setPen(QPen(Qt::red, 3));
painter.setBrush(QBrush( Qt::red, Qt::SolidPattern));
painter.drawEllipse(moveX,moveY,50,50);

if (increment)
   switch(phase)
      {
   case 0:
           if (moveX<300) moveX++;
           else phase=1;
           break;
   case 1:
           if (moveX>100) moveX--;
           else phase=0;
           break;
      }

for (pos=objects.begin();pos!=objects.end();pos++)
    switch((*pos)->type)
      {
        case circle:
                //linke obere Ecke: Breite == Hoehe == 50
        x=(*pos)->x-25;
                y=(*pos)->y-25;
                painter.setPen(QPen(Qt::green, 3));
                painter.setBrush(QBrush( Qt::green, Qt::Dense5Pattern));
                painter.drawEllipse(x,y,50,50);
      break;
        case square:
        //linke obere Ecke: Breite == Hoehe == 50
        x=(*pos)->x-25;
                y=(*pos)->y-25;
                painter.setPen(QPen(Qt::green, 3));
                painter.setBrush(QBrush( Qt::green, Qt::Dense5Pattern));
                painter.drawRect(x,y,50,50);
      break;
      }
painter.end();
}

void zeichenFeld::mousePressEvent(QMouseEvent *event)
{
lastX = event->x();
lastY = event->y();
}

void zeichenFeld::placeObject(enum drawType useType)
{
struct myDrawingObject *object;

object=new myDrawingObject;
object->type = useType;
object->x=lastX;
object->y=lastY;

objects.push_back(object);

update();
}

void zeichenFeld::serialize(QFile &file)
{
vector<struct myDrawingObject *>::iterator pos;

QTextStream out(&file);

out << "m" << moveX << " " << moveY << endl;

for (pos=objects.begin();pos!=objects.end();pos++)
    {
    out  << "m"
         << (*pos)->type << " "
         << (*pos)->x << " " << (*pos)->y <<endl;
   }
}

void zeichenFeld::deserialize(QFile &file)
{
struct myDrawingObject *object;
char c,d;
int x, y, type;
bool check = false;

QTextStream in(&file);

while (in.status() == QTextStream::Ok)
      {
      in >> c;
        if (in.status() == QTextStream::ReadPastEnd) break;

      if (c!='m')
         {
         QMessageBox::warning(this, tr("Objektfehler"),
                   tr("Folgender Objekttyp ist unbekannt: ") + c,QMessageBox::Ok);
         return;
         }
      object=new struct myDrawingObject;

      if(check==false)
      {
      in >> moveX >> moveY;
      check = true;
      in >> d;
      }

      in >> type;
      if(type==0)
      {
      object->type=0;
      }
      else
      object->type=1;
      in >> object->x >> object->y;

      in >> d; // Leerstellen werden vom '>>' Operator 'konmsumiert';
               // Zeilenenden nicht.

      objects.push_back(object);
      }

update();
}

Re: enum in Qt nicht mit int-Werten ansprechbar??

Verfasst: 17. Juli 2011 17:34
von Christian81
Da es keinen Operator << gibt welcher Dir deinen enum-Wert zurückgibt bleibt Dir nur der Umweg über einen temporären int-Wert.

Re: enum in Qt nicht mit int-Werten ansprechbar??

Verfasst: 17. Juli 2011 17:39
von Morlockk
Okay, danke. Habe das Ganze jetzt so gelöst...
Trotzdem gibt es noch Probleme mit der Deserialisierung.

Ich kriege die Daten problemlos in einer vernünftigen Form in eine Datei geschrieben, aber beim Laden wird lediglich der bewegliche rote Kreis an die richtige Stelle gesetzt, die vorher erzeugten grünen Kreise und Quadrate zeichnet er nicht wieder. Außerdem "löscht" er auch die Zeichenfläche nicht. Es bleiben also auch die Objekte drauf die vorher zu sehen waren...

Code: Alles auswählen

#include <QtGui>
#include <math.h>
#include "zeichenFeld.h"


zeichenFeld::zeichenFeld(QWidget *parent)
     : QWidget(parent)
{
setPalette(QPalette(QColor(250, 250, 200)));
setAutoFillBackground(true);
setMouseTracking(false);

increment=0;
phase=0;
moveX=100;
moveY=100;

timer=new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
}



zeichenFeld::~zeichenFeld()
{
for (vector<struct myDrawingObject *>::iterator pos=objects.begin();pos!=objects.end();pos++)
    delete *pos;
}

void zeichenFeld::paintEvent(QPaintEvent * )
{
QPainter painter;
vector<struct myDrawingObject *>::iterator pos;
int x,y;

painter.begin(this);

for (pos=objects.begin();pos!=objects.end();pos++)
    switch((*pos)->type)
      {
        case circle:
                //linke obere Ecke: Breite == Hoehe == 50
        x=(*pos)->x-25;
                y=(*pos)->y-25;
                painter.setPen(QPen(Qt::green, 3));
                painter.setBrush(QBrush( Qt::green, Qt::Dense5Pattern));
                painter.drawEllipse(x,y,50,50);
      break;
        case square:
        //linke obere Ecke: Breite == Hoehe == 50
        x=(*pos)->x-25;
                y=(*pos)->y-25;
                painter.setPen(QPen(Qt::green, 3));
                painter.setBrush(QBrush( Qt::green, Qt::Dense5Pattern));
                painter.drawRect(x,y,50,50);
      break;
      }

painter.setPen(QPen(Qt::red, 3));
painter.setBrush(QBrush( Qt::red, Qt::SolidPattern));
painter.drawEllipse(moveX,moveY,50,50);

if (increment)
   switch(phase)
      {
   case 0:
           if (moveX<300) moveX++;
           else phase=1;
           break;
   case 1:
           if (moveX>100) moveX--;
           else phase=0;
           break;
      }


painter.end();
}

void zeichenFeld::mousePressEvent(QMouseEvent *event)
{
lastX = event->x();
lastY = event->y();
}

void zeichenFeld::placeObject(enum drawType useType)
{
struct myDrawingObject *object;

object=new myDrawingObject;
object->type = useType;
object->x=lastX;
object->y=lastY;

objects.push_back(object);

update();
}

void zeichenFeld::serialize(QFile &file)
{
vector<struct myDrawingObject *>::iterator pos;

QTextStream out(&file);

out << "m" << moveX << " " << moveY << endl;

for (pos=objects.begin();pos!=objects.end();pos++)
    {
    out  << "m"
         << (*pos)->type << " "
         << (*pos)->x << " " << (*pos)->y <<endl;
   }
}

void zeichenFeld::deserialize(QFile &file)
{
struct myDrawingObject *object;
char c,d;
int x, y, type;
bool check = false;

QTextStream in(&file);

while (in.status() == QTextStream::Ok)
      {
      in >> c;

      if (in.status() == QTextStream::ReadPastEnd) break;

      if (c!='m')
         {
         QMessageBox::warning(this, tr("Objektfehler"),
                   tr("Folgender Objekttyp ist unbekannt: ") + c,QMessageBox::Ok);
         return;
         }
      object=new struct myDrawingObject;

      if(check==false)
      {
      in >> moveX >> moveY;
      check = true;
      in >> d;
      }

      in >> type;
      if(type==0)
      {
      object->type=square;
      }
      else
      object->type=circle;

      in >> x >> y;

      object->x=x;
      object->y=y;

      in >> d; // Leerstellen werden vom '>>' Operator 'konmsumiert';
               // Zeilenenden nicht.

      objects.push_back(object);
      }

update();
}