Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Moved] determing subclass of QGraphicsItem
Forum Updated to NodeBB v4.3 + New Features

[Moved] determing subclass of QGraphicsItem

Scheduled Pinned Locked Moved General and Desktop
12 Posts 5 Posters 5.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DenisKormalev
    wrote on last edited by
    #2

    Can you show more code please? What you've shown should work if all other is ok.

    1 Reply Last reply
    0
    • D Offline
      D Offline
      daviddc1979
      wrote on last edited by
      #3

      Hi,

      I will paste the advance function of the GraphicsItemBullet below...
      What I try to do (to learn the Graphics of Qt) is to show one moving 'shield' en two moving 'bullets'.
      In case the bullet hits the shield, the bullet should turn.
      In case the bullet hits another bullet, a new bullet will be created
      (I will have to implement a limit of number of bullets to avoid an overflow)

      @
      // implement protected functions

      void GraphicsItemBullet::advance(int phase)
      {
      if (!phase) return;

      // turn in case to close to the border
      QRectF r = boundingRect();
      QPointF mypoint(pos());
      if (mypoint.x() > (500-r.width())) directionX = -1;
      if (mypoint.x() < 1) directionX = 1;
      if (mypoint.y() > (500-r.height())) directionY = -1;
      if (mypoint.y() < 1) directionY = 1;
      
      
      // turn to avoid collision with shield
      // and create a new bullet in case two bullets have collision
      QList<QGraphicsItem *> itemlist = scene()->items();
      foreach (QGraphicsItem *item, itemlist) {
          if (item == this) continue;
          if (item->type() == GraphicsItemShield::Type) {
             QPointF checkpoint(item->pos());
             if ((mypoint.x() > checkpoint.x() - 30)
                  && (mypoint.x() < checkpoint.x() + 30)
                  && (mypoint.y() > checkpoint.y() - 30)
                  && (mypoint.y() < checkpoint.y() + 30))
             {
                 directionX = directionX * -1;
                 directionY = directionY * -1;
             }
          } // if type = GraphicsItemShield
      
          if (item->type() == GraphicsItemBullet::Type) {
             QPointF checkpoint(item->pos());
             if ((mypoint.x() == checkpoint.x())
                  && (mypoint.y() == checkpoint.y())
                 )
             {
                 GraphicsItemBullet *bullet = new GraphicsItemBullet;
                 bullet->setPos(5, 5);
                 scene()->addItem(bullet);
             }
          } // if type = GraphicsItemBullet
      } // for each...
      
      // move
      setPos(mapToParent(1 * directionX, 1 * directionY));
      

      }

      @

      1 Reply Last reply
      0
      • T Offline
        T Offline
        thisisbhaskar
        wrote on last edited by
        #4

        one thing you can do is to do a qobject_cast

        @foreach (QGraphicsItem item, itemlist) {
        // ...
        if(qobject_cast<GraphicsItemShield
        >(item)) {
        // item is GraphicsItemShield type
        } else if(qobject_cast<GraphicsItemBullet*>(item) {
        // item is GraphicsItemBullet type
        }
        }
        @

        1 Reply Last reply
        0
        • D Offline
          D Offline
          DenisKormalev
          wrote on last edited by
          #5

          qgraphicsitem_cast fits here better. These items can be derived from QGraphicsItem, not QGraphicsObject. In this case qobject_cast will not work.

          daviddc, can you show headers with these classes and their type() methods?

          1 Reply Last reply
          0
          • R Offline
            R Offline
            rokemoon
            wrote on last edited by
            #6

            Change qobject_cast on static_cast
            @
            foreach (QGraphicsItem item, itemlist) {
            // ...
            if(static_cast<GraphicsItemShield
            >(item)) {
            // item is GraphicsItemShield type
            } else if(static_cast<GraphicsItemBullet*>(item) {
            // item is GraphicsItemBullet type
            }
            }
            @
            With type() you can make like this, implement common enum
            @
            enum { ShieldType = QGraphicsItem::UserType + 1,
            BulletType };
            @
            In class GraphicsItemShield reimplement func
            @int GraphicsItemShield::type () const { return ShieldType; }@
            In class GraphicsItemBullet reimplement func
            @int GraphicsItemBullet::type () const { return BulletType; }@

            and in your code
            @
            //...
            // turn to avoid collision with shield
            // and create a new bullet in case two bullets have collision
            QList<QGraphicsItem *> itemlist = scene()->items();
            foreach (QGraphicsItem *item, itemlist) {
            if (item == this) continue;
            switch (item->type())
            {
            case ShieldType: //do smth
            break;
            case BulletType: //do another smth
            break;
            }
            //...
            }
            @
            swith gives you more scalable code (because if you, for example, want MagicBulletItem :-) just add another case)

            1 Reply Last reply
            0
            • EddyE Offline
              EddyE Offline
              Eddy
              wrote on last edited by
              #7

              @
              enum { ShieldType = QGraphicsItem::UserType + 1,
                     BulletType };
              @

              You didn't set BulletType like you did with ShieldType

              Qt Certified Specialist
              www.edalsolutions.be

              1 Reply Last reply
              0
              • R Offline
                R Offline
                rokemoon
                wrote on last edited by
                #8

                enum do it automatic (he iterate BulletType him self using the previous value, BulletType = ShieldType + 1 and so on)

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  DenisKormalev
                  wrote on last edited by
                  #9

                  Adding enum with single value in each class will be better.

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    rokemoon
                    wrote on last edited by
                    #10

                    [quote author="Denis Kormalev" date="1307294343"]Adding enum with single value in each class will be better.[/quote]
                    of course, but in this case programmer must watch the iteration he did. He can mistake and did like this
                    @
                    int GraphicsItemShield::type () const
                    {
                    return QGraphicsItem::UserType + 1;
                    }
                    @

                    @
                    int GraphicsItemBullet::type () const
                    {
                    return QGraphicsItem::UserType + 1;
                    }
                    @
                    Update: and if you want to add another class you just add ClassNameType to enum and return this in new class
                    Sorry if I undestood you wrong

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      daviddc1979
                      wrote on last edited by
                      #11

                      Hi,

                      Thanks for your feedback
                      I'm rather late home from work
                      I will give it a try tomorrow and let you know :)

                      David DC

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        daviddc1979
                        wrote on last edited by
                        #12

                        Hi,

                        I have Holiday and found some time to try out your advice.

                        It works fine with enum type.

                        @
                        enum { ShieldType = QGraphicsItem::UserType + 1, BulletType };
                        @

                        thanks for your support.

                        Kind regards,
                        David DC

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved