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. The function QGraphicsScene::itemAt problem
Forum Updated to NodeBB v4.3 + New Features

The function QGraphicsScene::itemAt problem

Scheduled Pinned Locked Moved General and Desktop
2 Posts 2 Posters 4.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.
  • Y Offline
    Y Offline
    yaseminyilmaz
    wrote on last edited by
    #1

    Hi all,

    I've created a custom class (named as Flow) inherited by QGraphicsItem. It's composing of an arrow and curve. I've used the function itemAt to determine which item has selected when QGraphicsScene::mousePressEvent is called. But it does not always return correct item. Otherwise I've written the folllowing function for manual detection. It's working correctly. But I want to learn why sometimes QGraphicsScene can not detect item selected by pressing mouse? Is there a more sensible method than manual point control?

    @
    int getMatchedFlow(QPointF pos)
    {
    int fID = -1;
    QList<Flow*> mFlowList = mGroupStore.keys();
    QList<Flow*>::iterator i;
    Flow *pFlow;

    for (i = mFlowList.begin(); i != mFlowList.end(); ++i)
    {
        pFlow = (Flow*)*i;
        if (pFlow->checkPointSet(pos))
        {
            fID = pFlow->getID();
            break;
        }
    }
    
    return fID;
    

    }

    bool Flow::checkPointSet(QPointF point)
    {
    bool rc = false;

    if (mBoundingPath.contains(point))
    {
        rc = true;
    }
    
    return rc;
    

    }
    @

    Thanks a lot for your helps,

    1 Reply Last reply
    0
    • G Offline
      G Offline
      gmaro
      wrote on last edited by
      #2

      Hi,

      Too bad that you didn't share the code that is not working...

      I think you're doing this really wrong and may have some serious trouble in future with your approach, however few good solutions that you may use:

      There are much better ways to determine the selected item...

      If you don't want to use the QGraphicsObject, allow your items to be really selected by setFlag(QGraphicsItem::ItemIsSelectable, true), now in event, iterate over items and check it by isSelected()

      Use QGraphicsObject Instead of QGraphicsItem, reimplement the mousePressEvent, put the emit some singal inside and catch the signal.

      Look at some sample code that I wrote for you (It's not about the code quality, I just want to give you an idea):

      header:
      @
      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H

      #include <QtGui>

      class TextItem : public QGraphicsTextItem
      {
      Q_OBJECT
      public:
      TextItem( const QString & text, QGraphicsItem * parent = 0 )
      : QGraphicsTextItem( text, parent )
      {
      //Optional
      //setFlag(QGraphicsItem::ItemIsMovable, true);
      //setFlag(QGraphicsItem::ItemIsSelectable, true);
      }

      void mousePressEvent( QGraphicsSceneMouseEvent *e )
      {
          qDebug() << __PRETTY_FUNCTION__;
          emit itemClicked();
          QGraphicsTextItem::mousePressEvent( e );
      }
      

      signals:
      void itemClicked();
      };

      namespace Ui {
      class MainWindow;
      }

      class MainWindow : public QMainWindow
      {
      Q_OBJECT

      public:
      explicit MainWindow(QWidget *parent = 0);
      ~MainWindow();

      private:
      QGraphicsScene *scene;
      QGraphicsView *view;

      private slots:
      void onItemClicked();
      };

      #endif // MAINWINDOW_H
      @

      source:
      @
      #include "mainwindow.h"
      #include <QDebug>

      MainWindow::MainWindow(QWidget *parent) :
      QMainWindow(parent)
      {

      view = new QGraphicsView();
      scene = new QGraphicsScene();
      view->setScene( scene );
      view->setSceneRect( view->rect() );
      scene->setSceneRect( view->rect() );
      scene->setBackgroundBrush( Qt::white );
      
      setCentralWidget( view );
      
      TextItem *t = new TextItem( "Item 1" );
      TextItem *t2 = new TextItem( "Item 2" );
      scene->addItem( t );
      scene->addItem( t2 );
      t->setPos( scene->sceneRect().topLeft() );
      t2->setPos( scene->sceneRect().center() );
      QObject::connect( t, SIGNAL(itemClicked()), this, SLOT(onItemClicked()) );
      QObject::connect( t2, SIGNAL(itemClicked()), this, SLOT(onItemClicked()) );
      

      }

      void MainWindow::onItemClicked()
      {
      TextItem ti = qobject_cast<TextItem>( sender() );
      if ( ti != 0 ) {
      qDebug() << PRETTY_FUNCTION << ti->document()->toPlainText();
      }
      }
      @

      Please note the "Optional" commented code, uncomment them to se the change.
      Of course you can use signal mapper and many more to get it better, it's just an idea.

      By the way. I strongly recommend the "Diagram Scene example":http://doc.qt.nokia.com/4.7-snapshot/graphicsview-diagramscene.html.

      Hope that helps.

      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