Results 1 to 9 of 9

Thread: Subclassing QGraphicsPixmapItem ???

  1. #1
    Join Date
    Apr 2016
    Posts
    23
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Subclassing QGraphicsPixmapItem ???

    I'm trying to establish an array of QGraphicsPixmapItems.

    Qt Code:
    1. // Pre-Try as a general check:
    2.  
    3. QPixmap pixmapA = QPixmap( ":/images/imageA.png" );
    4. QGraphicsPixmapItem pixmapItemA;
    5. pixmapItemA.setPixmap( pixmapA );
    6.  
    7. // This works
    To copy to clipboard, switch view to plain text mode 

    But then:

    Qt Code:
    1. // First Try
    2.  
    3. QVector< QGraphicsPixmapItem > itemVector( 100 );
    4. itemVector[23].setPixmap( pixmapA );
    5.  
    6. // Fails: In QGraphicsPixmapItem, 'DISABLE COPY' is private
    To copy to clipboard, switch view to plain text mode 

    And:

    Qt Code:
    1. // Second Try:
    2.  
    3. QVector< QGraphicsPixmapItem > itemVector( 100 );
    4. QGraphicsPixmapItem pixmapItemA;
    5. pixmapItemA.setPixmap( pixmapA );
    6. itemVector[23] = pixmapItemA;
    7.  
    8. // Fails: In QGraphicsPixmapItem, 'operator=' is private
    To copy to clipboard, switch view to plain text mode 

    And, finally:

    Qt Code:
    1. // Third Try:
    2.  
    3. QVector< QGraphicsItem > itemVector( 100 );
    4. QGraphicsPixmapItem pixmapItemA;
    5. pixmapItemA.setPixmap( pixmapA );
    6. itemVector[23] = pixmapItemA;
    7.  
    8. // Fails - invalid abstract return type 'QGraphicsItem'
    To copy to clipboard, switch view to plain text mode 

    Is there something I'm missing?

    Or, am I going to have to subclass QGraphicsPixmapItem in order to get this to work?

    If the latter, could somebody please point me to a reasonably straightforward link on subclassing? I've never tried anything like that and have numerous trepidations.

    BTW, I do note in qglobal.h :

    Qt Code:
    1. /*
    2.   Some classes do not permit copies to be made of an object. These
    3.   classes contains a private copy constructor and assignment
    4.   operator to disable copying (the compiler gives an error message).
    5. */
    6. #define Q_DISABLE_COPY(Class) \
    7. Class(const Class &) Q_DECL_EQ_DELETE;\
    8. Class &operator=(const Class &) Q_DECL_EQ_DELETE;
    To copy to clipboard, switch view to plain text mode 

    Why would copies not be permitted? If there's a valid reason, subclassing to get past it might break something, in which case Qt would seem not to be what I need to use ???
    Last edited by mdavidjohnson; 2nd November 2016 at 00:45.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    Vector of pointers to QGraphicsPixmapItem

    Qt Code:
    1. QVector< QGraphicsPixmapItem*> itemVector( 100 );
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  3. #3
    Join Date
    Apr 2016
    Posts
    23
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    Thanks -

    That does indeed work with my short sample.

    I'll try to extend it to the entire chess board.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    Why are you storing your QGraphicsPixmapItem instances in a QVector in the first place? You should be adding them to your QGraphicsScene, where they will be properly parented (and their lifetimes managed by the scene). If you need to keep a copy of the *pointer* for ease of use, keep that in the QVector as well as adding *the same pointer* to the scene, but remember that after the item has been destroyed by the scene it will no longer point to a valid instance.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Apr 2016
    Posts
    23
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    To anda_skoa and d_stranz --

    To anda_skoa:

    Unfortunately, it doesn't seem to have worked when extended to the entire chess board.

    Here's an abbreviated sample to show what's happening.

    First, a successful test without the vector:

    Qt Code:
    1. // ChessTest2
    2. // MDJ 2016/11/02
    3.  
    4. // Qt 5.7 - Qt Creator 4.0.2 - Qt Widgets Application
    5. // No changes to files other than this main.cpp - except:
    6. // Added line "RESOURCES += application.qrc" to ChessTest2.pro.
    7. // Added images folder with files:
    8. // blackSquare.png
    9. // whiteSquare.png
    10. // Added application.qrc Resources file:
    11. // <!DOCTYPE RCC><RCC version="1.0">
    12. // <qresource>
    13. // <file>images/blackSquare.png</file>
    14. // <file>images/whiteSquare.png</file>
    15. // </qresource>
    16. // </RCC>
    17.  
    18. // This test compiles:
    19. // and runs as expected, displaying a "black" square
    20. // and a "white" square in the lower left corner
    21. // of the view.
    22.  
    23. #include "mainwindow.h"
    24. #include <QApplication>
    25. #include <QPixmap>
    26. #include <QGraphicsPixmapItem>
    27. #include <QGraphicsScene>
    28. #include <QGraphicsView>
    29.  
    30. int main( int argc, char **argv )
    31. {
    32. QApplication app(argc, argv);
    33.  
    34. // Load the Resource Graphics
    35. QPixmap pixmapBlackSquare = QPixmap( ":/images/blackSquare.png" );
    36. QPixmap pixmapWhiteSquare = QPixmap( ":/images/whiteSquare.png" );
    37.  
    38. // Establish the Scene
    39. scene.setSceneRect( -370.0, -370.0, 740.0, 740.0 );
    40.  
    41. // Set up the Board
    42. QGraphicsPixmapItem pixmapItem0;
    43. pixmapItem0.setPixmap( pixmapBlackSquare );
    44. pixmapItem0.setPos( -370, 296 );
    45. scene.addItem( &pixmapItem0 );
    46.  
    47. QGraphicsPixmapItem pixmapItem1;
    48. pixmapItem1.setPixmap( pixmapWhiteSquare );
    49. pixmapItem1.setPos( -296, 296 );
    50. scene.addItem( &pixmapItem1 );
    51.  
    52. // Establish the View
    53. QGraphicsView view( &scene );
    54. view.setGeometry( 400, 200, 760, 760 );
    55. view.setRenderHints( QPainter::Antialiasing );
    56. view.show();
    57.  
    58. return app.exec();
    59. }
    To copy to clipboard, switch view to plain text mode 

    And then the unsuccessful test with the vector:

    Qt Code:
    1. // ChessVectorTest2
    2. // MDJ 2016/11/02
    3.  
    4. // Qt 5.7 - Qt Creator 4.0.2 - Qt Widgets Application
    5. // No changes to files other than this main.cpp - except:
    6. // Added line "RESOURCES += application.qrc" to ChessTest2.pro.
    7. // Added images folder with files:
    8. // blackSquare.png
    9. // whiteSquare.png
    10. // Added application.qrc Resources file:
    11. // <!DOCTYPE RCC><RCC version="1.0">
    12. // <qresource>
    13. // <file>images/blackSquare.png</file>
    14. // <file>images/whiteSquare.png</file>
    15. // </qresource>
    16. // </RCC>
    17.  
    18. // This test compiles:
    19. // but displays nothing
    20. // and reports no errors
    21.  
    22. #include "mainwindow.h"
    23. #include <QApplication>
    24. #include <QPixmap>
    25. #include <QGraphicsPixmapItem>
    26. #include <QGraphicsScene>
    27. #include <QGraphicsView>
    28. #include <QVector>
    29.  
    30. int main( int argc, char **argv )
    31. {
    32. QApplication app(argc, argv);
    33.  
    34. // Load the Resource Graphics
    35. QPixmap pixmapBlackSquare = QPixmap( ":/images/blackSquare.png" );
    36. QPixmap pixmapWhiteSquare = QPixmap( ":/images/whiteSquare.png" );
    37.  
    38. // Establish the Scene
    39. scene.setSceneRect( -370.0, -370.0, 740.0, 740.0 );
    40.  
    41. // Set up the Board
    42. QVector< QGraphicsPixmapItem* > boardVector( 2 );
    43.  
    44. boardVector[ 0 ]->setPixmap( pixmapBlackSquare );
    45. boardVector[ 0 ]->setPos( -370, 296 );
    46. scene.addItem( boardVector[ 0 ] );
    47.  
    48. boardVector[ 1 ]->setPixmap( pixmapWhiteSquare );
    49. boardVector[ 1 ]->setPos( -296, 296 );
    50. scene.addItem( boardVector[ 1 ] );
    51.  
    52. // Establish the View
    53. QGraphicsView view( &scene );
    54. view.setGeometry( 400, 200, 760, 760 );
    55. view.setRenderHints( QPainter::Antialiasing );
    56. view.show();
    57.  
    58. return app.exec();
    59. }
    To copy to clipboard, switch view to plain text mode 

    Without any error messages, I'm pretty much lost.


    Added after 10 minutes:


    To d_stranz:

    I'm trying to organize the QGraphicsPixmapItems into a QVector and then add the individual vector entries to the scene. This will facilitate subsequent logic.

    This is a chess board. The squares are added to the scene, and the pieces will be added with the squares as parents. This will facilitate checking how many attacks are currently leveled at a given square and the legality of proposed moves. It will also facilitate the actual moves themselves by setting a new parent for the piece in question.
    Last edited by mdavidjohnson; 2nd November 2016 at 19:16.

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    Quote Originally Posted by mdavidjohnson View Post
    Qt Code:
    1. // Set up the Board
    2. QVector< QGraphicsPixmapItem* > boardVector( 2 );
    3.  
    4. boardVector[ 0 ]->setPixmap( pixmapBlackSquare );
    To copy to clipboard, switch view to plain text mode 
    Here you are accessing an uninitialized pointer.
    The vector contains "space" for pointers, you need to put pointers to objects into it.
    Qt Code:
    1. boardVector[ 0 ] = new QGraphicsPixmapItem();
    2. boardVector[ 0 ]->setPixmap( pixmapBlackSquare );
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by mdavidjohnson View Post
    Without any error messages, I'm pretty much lost.
    This should have crashed in the first line where you access an invalid pointer.

    Cheers,
    _

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    I'm trying to organize the QGraphicsPixmapItems into a QVector and then add the individual vector entries to the scene. This will facilitate subsequent logic.
    It actually doesn't matter in which order you do this, so long as at some point you *do* add the items to the scene. Just remember that when your item is destroyed by the scene, the pointer stored in the QVector will not be valid. Do not delete the pointers that you add to the QVector; they will automatically be deleted by the scene.

    the pieces will be added with the squares as parents
    You might want to rethink that, since the pieces will be moving from square to square and thus will be reparented often. You might want to make them direct children of the scene, but set their z-numbers so they are drawn on top of their respective squares. It will be very easy to keep track of which piece is on which square if you make two reciprocal QMaps: one that maps piece to square, the other that maps square to piece.

    Regardless, it would probably be a better design to model the game independently of the display of the game. That is, instead of using QGraphicsPixmap items to represent the actual pieces in the game, model the board, pieces, and rules in a display-independent model. Use signals and slots to communicate changes in the board position, etc. to update the scene. By doing this, you can develop the game rules independently of how you display the board, and can get the logic for that working correctly without also getting all tied up in the game display at the same time. You'll also find it easier to change how the game is displayed, because you won't have to also change the game logic at the same time.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  8. #8
    Join Date
    Apr 2016
    Posts
    23
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    anda_skoa and d_franz --

    BTW, When I reply to two different posts, how can I force the system to publish them as two separate posts instead of combining them like this one?

    Thank you, anda_skoa -

    That does seem to have fixed it.

    I'm not sure why it didn't crash before though.


    Added after 23 minutes:


    Thank you, d_franz -

    Using two reciprocal QMaps is an intriguing idea. And I like the concept of separating the logic from the display.

    But I wonder if the overhead of repeatedly referring to the maps might exceed the benefits.

    For a simplified example, suppose I have a White Bishop at a1. It's potential moves would then be limited to b2, c3, d4, e5, f6, g7, and h8.

    We check b2 and there's nothing on that square, so it's possible to move to b2.

    We check c3 and there's a piece on it. If it is a White piece, it's not possible to move to c3. If it is a Black piece, it's possible to move to c3 with a capture.

    In either case, our checking is short-circuited: There's no need to check d4, e5, f6, g7, or h8 because our Bishop cannot move past c3.

    But, as an extended example, a Queen on a central square might have to check as many as 7 + 7 + 7 + 7 = 28 different squares for move legality.

    I will think more on this.

    Would reciprocal QHashs be superior to QMaps for this application?
    Last edited by mdavidjohnson; 3rd November 2016 at 23:05.

  9. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Subclassing QGraphicsPixmapItem ???

    But, as an extended example, a Queen on a central square might have to check as many as 7 + 7 + 7 + 7 = 28 different squares for move legality.
    This is why it took decades for IBM to teach Big Blue to play master-level chess. And that isn't even considering look-ahead or strategy.

    Map lookup -is- hash-based, the main difference being that QMap iterators return entries in key-sorted order, whereas QHash entries are arbitrarily ordered. If you don't have a need for ordering pieces or squares, then a QHash would work fine. (I would presume your keys would be the names of the squares or something like "wb1" for pieces, which are unique).

    Lookups are extremely fast, so even if you did have 28 potential moves, checking them all would be quick. That particular scenario is the worst case anyway - for other pieces and for more typical piece placements, the number of things you'd need to check would be much less before you were blocked by another piece or ran off the edge of the board. I think I would also compute the allowed moves on the fly, using rules for each piece, rather than try to build a lookup table for each piece at each location on the board. That is, knowing the position of a white bishop ("x,y"), you know that it has potential moves to (x+1, y+2), (x-1, y+2), (x+1, y-2), (x-1, y-2), (x+2, y-1), etc., if I remember my chess rules correctly, so long as the target squares are on the board and not occupied by a piece of the same color. For a queen at (x,y), the rules are (x+n, y+n; n <=7), (x+n, y; n<=7), etc.

    It is always good to separate logic from visualization. As you get the logic right, you can report the game moves as text (wb a1 ->c3) and worry about displaying it graphically later. You're probably going to want to create game log anyway, so that's how you'd report it.
    Last edited by d_stranz; 4th November 2016 at 16:57.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. problem with QGraphicsPixmapItem
    By JustJ in forum Newbie
    Replies: 2
    Last Post: 4th November 2014, 10:14
  2. QGraphicsPixmapItem
    By erfan in forum Qt Programming
    Replies: 1
    Last Post: 13th June 2012, 22:54
  3. subclassing QGraphicsItem, QGraphicsPixmapItem
    By rogerholmes in forum Newbie
    Replies: 3
    Last Post: 27th August 2009, 00:12
  4. Shape of QGraphicsPixmapItem
    By StefanHirche in forum Newbie
    Replies: 4
    Last Post: 5th September 2007, 16:14
  5. QGraphicsPixmapItem performance
    By cerber in forum Qt Programming
    Replies: 21
    Last Post: 22nd August 2007, 14:41

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.