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
    daviddc1979
    wrote on last edited by
    #1

    hello,

    I have created two subclasses of QGraphicsItem:

    • GraphicsItemShield
    • GraphicsItemBullet

    I have the following loop
    @
    foreach (QGraphicsItem *item, itemlist) {
    // ...
    }
    @

    and I like to know of the item is a GraphicsItemShield or a GraphicsItemBullet...

    If have tried:
    @
    if (item->type() == GraphicsItemShield::Type) {
    // ...
    }
    @

    but it doesn't work :-(

    Any idea?

    Thanks for your support.
    Kind regards,
    David DC

    1 Reply Last reply
    0
    • 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