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. QGraphicsScene::scenePos().toPoint() behaviour
QtWS25 Last Chance

QGraphicsScene::scenePos().toPoint() behaviour

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 310 Views
  • 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.
  • S Offline
    S Offline
    SeppyQT
    wrote on last edited by SeppyQT
    #1

    I have experienced a weird behaviour in QGraphicsScene

    Background:
    Programm creates a Part of a roof. You can put modules on this roof. If you want you can save this state as a XML file.
    Saving and loading works good.
    But if you add new Modules on it, it "forgets" the position of the old modules, except if you move them, than the new Position is saved.

    But in the case you just want to add one or two Modules without moving the old ones. The item->scenePos().toPoint() will return x=0,y=0;

    void RoofTab::onAddClick()
    {
    	int width = qobject_cast<QLineEdit*>(this->widgets.value("tb_width"))->text().toInt();
    	int height = qobject_cast<QLineEdit*>(this->widgets.value("tb_height"))->text().toInt();
    	short type = qobject_cast<QComboBox*>(this->widgets.value("cbType"))->currentIndex();
    	//auto colour = qobject_cast<WidgetColorPicker*>(this->widgets.value("cp_string"))->getColor();
    	auto colour = QColor(qobject_cast<QComboBox*>(this->widgets.value("cbcolour"))->currentText());
    	auto stringNo = qobject_cast<QLineEdit*>(this->widgets.value("tb_string"))->text().toUInt();
    	auto manu = qobject_cast<QLineEdit*>(this->widgets.value("tb_manufacteurer"))->text();
    	auto model = qobject_cast<QLineEdit*>(this->widgets.value("tb_model"))->text();
    	uint64_t watt = qobject_cast<QLineEdit*>(this->widgets.value("tb_watt"))->text().toUInt();
    	CPVModulItem* item = [&]() {
    		if (type == 0) 
    			return new CPVModulItem(0, 0, width, height);
    		return new CPVModulItem(0, 0, height, width);
    	}();
    	item->setFlags(QGraphicsItem::GraphicsItemFlag::ItemIsSelectable | QGraphicsItem::GraphicsItemFlag::ItemIsFocusable | QGraphicsItem::GraphicsItemFlag::ItemIsMovable);
    	item->setBrush(QBrush(colour));
    	item->setHeight(height);
    	item->setWidth(width);
    	item->setStringNo(stringNo);
    	item->setManufacteurer(manu);
    	item->setModel(model);
    	item->setWatt(watt);
    	connect(item, &CPVModulItem::RightClick, this, &RoofTab::onPVContextMenu);
    	connect(item, &CPVModulItem::DelPress, this, [&](CPVModulItem* sender) {
    		if (QMessageBox::question(nullptr, QString::fromStdU32String(lang[rt]["DelQuestion"]["title"]), QString::fromStdU32String(lang[rt]["DelQuestion"]["body"]), QMessageBox::StandardButton::Yes, QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
    			this->mScene->removeItem(sender);
    		}
    		});
    	connect(item, &CPVModulItem::ArrowKey, this, &RoofTab::ArroyKeyPress);
    	this->mScene->addItem(item);
    }
    
    void RoofTab::addModule(const QPoint& pos, const QColor& colour, const Details& details) {
    	auto* el = new CPVModulItem(pos.x(), pos.y(), details.width, details.height);
    	el->setFlags(QGraphicsItem::GraphicsItemFlag::ItemIsSelectable | QGraphicsItem::GraphicsItemFlag::ItemIsFocusable | QGraphicsItem::GraphicsItemFlag::ItemIsMovable);
    	
    	el->setBrush(colour);
    	el->setWatt(details.Watt);
    	el->setManufacteurer(details.manufacteurer);
    	el->setModel(details.Model);
    	
    	el->setWidth(details.width);
    	el->setHeight(details.height);
    	el->setStringNo(details.string_no);
    	connect(el, &CPVModulItem::RightClick, this, &RoofTab::onPVContextMenu);
    	connect(el, &CPVModulItem::DelPress, this, [&](CPVModulItem* sender) {
    		if (QMessageBox::question(nullptr, QString::fromStdU32String(lang[rt]["DelQuestion"]["title"]), QString::fromStdU32String(lang[rt]["DelQuestion"]["body"]), QMessageBox::StandardButton::Yes, QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
    			this->mScene->removeItem(sender);
    		}
    		});
    	connect(el, &CPVModulItem::ArrowKey, this, &RoofTab::ArroyKeyPress);
    	this->mScene->addItem(el);
    }
    

    onAddClick() is in case you add Modules via Signal/Slot
    addModule is used to load the Module from XML.

    I am confused that the position is not saved :O

    EDIT:
    The Constructor of CPVModuleItem is:

    CPVModulItem::CPVModulItem(qreal x, qreal y, qreal width, qreal height, bool portrait, QGraphicsItem* parent) : QGraphicsRectItem(x, y, width, height, parent), backup_position(x,y)
    {
    }
    
    S Pl45m4P 2 Replies Last reply
    0
    • S SeppyQT

      I have experienced a weird behaviour in QGraphicsScene

      Background:
      Programm creates a Part of a roof. You can put modules on this roof. If you want you can save this state as a XML file.
      Saving and loading works good.
      But if you add new Modules on it, it "forgets" the position of the old modules, except if you move them, than the new Position is saved.

      But in the case you just want to add one or two Modules without moving the old ones. The item->scenePos().toPoint() will return x=0,y=0;

      void RoofTab::onAddClick()
      {
      	int width = qobject_cast<QLineEdit*>(this->widgets.value("tb_width"))->text().toInt();
      	int height = qobject_cast<QLineEdit*>(this->widgets.value("tb_height"))->text().toInt();
      	short type = qobject_cast<QComboBox*>(this->widgets.value("cbType"))->currentIndex();
      	//auto colour = qobject_cast<WidgetColorPicker*>(this->widgets.value("cp_string"))->getColor();
      	auto colour = QColor(qobject_cast<QComboBox*>(this->widgets.value("cbcolour"))->currentText());
      	auto stringNo = qobject_cast<QLineEdit*>(this->widgets.value("tb_string"))->text().toUInt();
      	auto manu = qobject_cast<QLineEdit*>(this->widgets.value("tb_manufacteurer"))->text();
      	auto model = qobject_cast<QLineEdit*>(this->widgets.value("tb_model"))->text();
      	uint64_t watt = qobject_cast<QLineEdit*>(this->widgets.value("tb_watt"))->text().toUInt();
      	CPVModulItem* item = [&]() {
      		if (type == 0) 
      			return new CPVModulItem(0, 0, width, height);
      		return new CPVModulItem(0, 0, height, width);
      	}();
      	item->setFlags(QGraphicsItem::GraphicsItemFlag::ItemIsSelectable | QGraphicsItem::GraphicsItemFlag::ItemIsFocusable | QGraphicsItem::GraphicsItemFlag::ItemIsMovable);
      	item->setBrush(QBrush(colour));
      	item->setHeight(height);
      	item->setWidth(width);
      	item->setStringNo(stringNo);
      	item->setManufacteurer(manu);
      	item->setModel(model);
      	item->setWatt(watt);
      	connect(item, &CPVModulItem::RightClick, this, &RoofTab::onPVContextMenu);
      	connect(item, &CPVModulItem::DelPress, this, [&](CPVModulItem* sender) {
      		if (QMessageBox::question(nullptr, QString::fromStdU32String(lang[rt]["DelQuestion"]["title"]), QString::fromStdU32String(lang[rt]["DelQuestion"]["body"]), QMessageBox::StandardButton::Yes, QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
      			this->mScene->removeItem(sender);
      		}
      		});
      	connect(item, &CPVModulItem::ArrowKey, this, &RoofTab::ArroyKeyPress);
      	this->mScene->addItem(item);
      }
      
      void RoofTab::addModule(const QPoint& pos, const QColor& colour, const Details& details) {
      	auto* el = new CPVModulItem(pos.x(), pos.y(), details.width, details.height);
      	el->setFlags(QGraphicsItem::GraphicsItemFlag::ItemIsSelectable | QGraphicsItem::GraphicsItemFlag::ItemIsFocusable | QGraphicsItem::GraphicsItemFlag::ItemIsMovable);
      	
      	el->setBrush(colour);
      	el->setWatt(details.Watt);
      	el->setManufacteurer(details.manufacteurer);
      	el->setModel(details.Model);
      	
      	el->setWidth(details.width);
      	el->setHeight(details.height);
      	el->setStringNo(details.string_no);
      	connect(el, &CPVModulItem::RightClick, this, &RoofTab::onPVContextMenu);
      	connect(el, &CPVModulItem::DelPress, this, [&](CPVModulItem* sender) {
      		if (QMessageBox::question(nullptr, QString::fromStdU32String(lang[rt]["DelQuestion"]["title"]), QString::fromStdU32String(lang[rt]["DelQuestion"]["body"]), QMessageBox::StandardButton::Yes, QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
      			this->mScene->removeItem(sender);
      		}
      		});
      	connect(el, &CPVModulItem::ArrowKey, this, &RoofTab::ArroyKeyPress);
      	this->mScene->addItem(el);
      }
      

      onAddClick() is in case you add Modules via Signal/Slot
      addModule is used to load the Module from XML.

      I am confused that the position is not saved :O

      EDIT:
      The Constructor of CPVModuleItem is:

      CPVModulItem::CPVModulItem(qreal x, qreal y, qreal width, qreal height, bool portrait, QGraphicsItem* parent) : QGraphicsRectItem(x, y, width, height, parent), backup_position(x,y)
      {
      }
      
      S Offline
      S Offline
      SeppyQT
      wrote on last edited by
      #2

      EDIT 2:
      if you move the old ones you get only the length of the way the moved.
      if you move them one pixel right and down you will get x=1,y=1
      if you move left and up you will get x=-1,y=-1

      1 Reply Last reply
      0
      • S SeppyQT

        I have experienced a weird behaviour in QGraphicsScene

        Background:
        Programm creates a Part of a roof. You can put modules on this roof. If you want you can save this state as a XML file.
        Saving and loading works good.
        But if you add new Modules on it, it "forgets" the position of the old modules, except if you move them, than the new Position is saved.

        But in the case you just want to add one or two Modules without moving the old ones. The item->scenePos().toPoint() will return x=0,y=0;

        void RoofTab::onAddClick()
        {
        	int width = qobject_cast<QLineEdit*>(this->widgets.value("tb_width"))->text().toInt();
        	int height = qobject_cast<QLineEdit*>(this->widgets.value("tb_height"))->text().toInt();
        	short type = qobject_cast<QComboBox*>(this->widgets.value("cbType"))->currentIndex();
        	//auto colour = qobject_cast<WidgetColorPicker*>(this->widgets.value("cp_string"))->getColor();
        	auto colour = QColor(qobject_cast<QComboBox*>(this->widgets.value("cbcolour"))->currentText());
        	auto stringNo = qobject_cast<QLineEdit*>(this->widgets.value("tb_string"))->text().toUInt();
        	auto manu = qobject_cast<QLineEdit*>(this->widgets.value("tb_manufacteurer"))->text();
        	auto model = qobject_cast<QLineEdit*>(this->widgets.value("tb_model"))->text();
        	uint64_t watt = qobject_cast<QLineEdit*>(this->widgets.value("tb_watt"))->text().toUInt();
        	CPVModulItem* item = [&]() {
        		if (type == 0) 
        			return new CPVModulItem(0, 0, width, height);
        		return new CPVModulItem(0, 0, height, width);
        	}();
        	item->setFlags(QGraphicsItem::GraphicsItemFlag::ItemIsSelectable | QGraphicsItem::GraphicsItemFlag::ItemIsFocusable | QGraphicsItem::GraphicsItemFlag::ItemIsMovable);
        	item->setBrush(QBrush(colour));
        	item->setHeight(height);
        	item->setWidth(width);
        	item->setStringNo(stringNo);
        	item->setManufacteurer(manu);
        	item->setModel(model);
        	item->setWatt(watt);
        	connect(item, &CPVModulItem::RightClick, this, &RoofTab::onPVContextMenu);
        	connect(item, &CPVModulItem::DelPress, this, [&](CPVModulItem* sender) {
        		if (QMessageBox::question(nullptr, QString::fromStdU32String(lang[rt]["DelQuestion"]["title"]), QString::fromStdU32String(lang[rt]["DelQuestion"]["body"]), QMessageBox::StandardButton::Yes, QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
        			this->mScene->removeItem(sender);
        		}
        		});
        	connect(item, &CPVModulItem::ArrowKey, this, &RoofTab::ArroyKeyPress);
        	this->mScene->addItem(item);
        }
        
        void RoofTab::addModule(const QPoint& pos, const QColor& colour, const Details& details) {
        	auto* el = new CPVModulItem(pos.x(), pos.y(), details.width, details.height);
        	el->setFlags(QGraphicsItem::GraphicsItemFlag::ItemIsSelectable | QGraphicsItem::GraphicsItemFlag::ItemIsFocusable | QGraphicsItem::GraphicsItemFlag::ItemIsMovable);
        	
        	el->setBrush(colour);
        	el->setWatt(details.Watt);
        	el->setManufacteurer(details.manufacteurer);
        	el->setModel(details.Model);
        	
        	el->setWidth(details.width);
        	el->setHeight(details.height);
        	el->setStringNo(details.string_no);
        	connect(el, &CPVModulItem::RightClick, this, &RoofTab::onPVContextMenu);
        	connect(el, &CPVModulItem::DelPress, this, [&](CPVModulItem* sender) {
        		if (QMessageBox::question(nullptr, QString::fromStdU32String(lang[rt]["DelQuestion"]["title"]), QString::fromStdU32String(lang[rt]["DelQuestion"]["body"]), QMessageBox::StandardButton::Yes, QMessageBox::StandardButton::No) == QMessageBox::StandardButton::Yes) {
        			this->mScene->removeItem(sender);
        		}
        		});
        	connect(el, &CPVModulItem::ArrowKey, this, &RoofTab::ArroyKeyPress);
        	this->mScene->addItem(el);
        }
        

        onAddClick() is in case you add Modules via Signal/Slot
        addModule is used to load the Module from XML.

        I am confused that the position is not saved :O

        EDIT:
        The Constructor of CPVModuleItem is:

        CPVModulItem::CPVModulItem(qreal x, qreal y, qreal width, qreal height, bool portrait, QGraphicsItem* parent) : QGraphicsRectItem(x, y, width, height, parent), backup_position(x,y)
        {
        }
        
        Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by
        #3

        @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

        But in the case you just want to add one or two Modules without moving the old ones. The item->scenePos().toPoint() will return x=0,y=0;

        At first glance, I would say it's an update issue (of your scene or your items). What are the x / y values directly after you add a new item to your scene? Do all items appear at the correct coordinates? What does the XML file look like if you add items and save them?
        What is backup_position(x, y) for?

        @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

        auto* el = new CPVModulItem(pos.x(), pos.y(), details.width, details.height);

        what does pos.x() pos.y() return here?

        @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

        CPVModulItem* item = & {
        if (type == 0)
        return new CPVModulItem(0, 0, width, height);
        return new CPVModulItem(0, 0, height, width);
        }();

        Of course it's (0/0), because you passed (0/0)


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        S 1 Reply Last reply
        0
        • Pl45m4P Pl45m4

          @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

          But in the case you just want to add one or two Modules without moving the old ones. The item->scenePos().toPoint() will return x=0,y=0;

          At first glance, I would say it's an update issue (of your scene or your items). What are the x / y values directly after you add a new item to your scene? Do all items appear at the correct coordinates? What does the XML file look like if you add items and save them?
          What is backup_position(x, y) for?

          @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

          auto* el = new CPVModulItem(pos.x(), pos.y(), details.width, details.height);

          what does pos.x() pos.y() return here?

          @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

          CPVModulItem* item = & {
          if (type == 0)
          return new CPVModulItem(0, 0, width, height);
          return new CPVModulItem(0, 0, height, width);
          }();

          Of course it's (0/0), because you passed (0/0)

          S Offline
          S Offline
          SeppyQT
          wrote on last edited by
          #4

          after loading all Items are placed correctly.

          auto* el = new CPVModulItem(pos.x(), pos.y(), details.width, details.height,this->getScene());
          	auto temp = el->scenePos().toPoint();
          

          temp is x=0,y=0

          and backup_position was for debugging earlier.

          @Pl45m4 said in QGraphicsScene::scenePos().toPoint() behaviour:

          Of course it's (0/0), because you passed (0/0)

          the mentioned function is to add a new Module. You move the item later with the mouse to the wanted position.

          I could bypass the wierd thing with using backup_position and save the new Position as

          auto bp = element->getBackupPosition();
          auto np = element->scenePos().toPoint(); //np = new Position
          QPoint pos((bp.x()+np.x()),(bp.y()+np.y());
          

          with that it saves the correct position of both old modules and new inserted modules.

          Pl45m4P 1 Reply Last reply
          0
          • S SeppyQT

            after loading all Items are placed correctly.

            auto* el = new CPVModulItem(pos.x(), pos.y(), details.width, details.height,this->getScene());
            	auto temp = el->scenePos().toPoint();
            

            temp is x=0,y=0

            and backup_position was for debugging earlier.

            @Pl45m4 said in QGraphicsScene::scenePos().toPoint() behaviour:

            Of course it's (0/0), because you passed (0/0)

            the mentioned function is to add a new Module. You move the item later with the mouse to the wanted position.

            I could bypass the wierd thing with using backup_position and save the new Position as

            auto bp = element->getBackupPosition();
            auto np = element->scenePos().toPoint(); //np = new Position
            QPoint pos((bp.x()+np.x()),(bp.y()+np.y());
            

            with that it saves the correct position of both old modules and new inserted modules.

            Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote on last edited by Pl45m4
            #5

            @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

            You move the item later with the mouse to the wanted position

            So if you add a new item / modul, it appears at the top left corner (0/0) first before you can move it by dragging to the correct position?!

            Do you call setPos(x, y) when you move your item with your mouse? Since your CPVModulItem inherits from QGraphicsRectItem which inherits QGraphicsItem, you need to update it's position by calling setPos(x, y), otherwise your CPVModulItem x and y will return the initial values, which are 0. Moving the item can cause the scene to update, so the position values get set and you get the updated (and correct) coords afterwards

            Show your mouseMoveEvent please or the part where you move your item(s).


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            S 1 Reply Last reply
            0
            • Pl45m4P Pl45m4

              @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

              You move the item later with the mouse to the wanted position

              So if you add a new item / modul, it appears at the top left corner (0/0) first before you can move it by dragging to the correct position?!

              Do you call setPos(x, y) when you move your item with your mouse? Since your CPVModulItem inherits from QGraphicsRectItem which inherits QGraphicsItem, you need to update it's position by calling setPos(x, y), otherwise your CPVModulItem x and y will return the initial values, which are 0. Moving the item can cause the scene to update, so the position values get set and you get the updated (and correct) coords afterwards

              Show your mouseMoveEvent please or the part where you move your item(s).

              S Offline
              S Offline
              SeppyQT
              wrote on last edited by
              #6

              @Pl45m4 said in QGraphicsScene::scenePos().toPoint() behaviour:

              So if you add a new item / modul, it appears at the top left corner (0/0) first before you can move it by dragging to the correct position?!

              yes you are right. if you add a new item it will appear top left corner.

              so I need to overload keyReleaseEvent for setPos ?
              but why does it save the new Modules correctly but not the old ones?

              Pl45m4P 1 Reply Last reply
              0
              • S SeppyQT

                @Pl45m4 said in QGraphicsScene::scenePos().toPoint() behaviour:

                So if you add a new item / modul, it appears at the top left corner (0/0) first before you can move it by dragging to the correct position?!

                yes you are right. if you add a new item it will appear top left corner.

                so I need to overload keyReleaseEvent for setPos ?
                but why does it save the new Modules correctly but not the old ones?

                Pl45m4P Offline
                Pl45m4P Offline
                Pl45m4
                wrote on last edited by Pl45m4
                #7

                @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

                so I need to overload keyReleaseEvent for setPos ?

                You could either do that or you update on mouseMove.

                You could also add something like a bool mouseDownOnItem member to your item class (but it's pretty much the same as reacting on QGraphicsItems mousePressEvent or mouseReleaseEvent directly

                @SeppyQT said in QGraphicsScene::scenePos().toPoint() behaviour:

                but why does it save the new Modules correctly but not the old ones

                Adding a new object to your scene will cause a repaint / update. So it updates existing items. Otherwise your items keep their initial values and item->pos() will return (0/0), because you didnt pass the actual position to your items base class (which is QGraphicsRectItem, which is a QGraphicsItem)

                Have a look at this (https://forum.qt.io/topic/49388/qgraphicsitem-mouse-press-event-return)


                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                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