uwerat / qskinny

A lightweight framework on top of the Qt scene graph and only few classes from Qt/Quick. It is usable from C++ and/or QML.
1.45k stars 293 forks source link

QskMenu ‘s position problem #446

Closed hestrro closed 1 month ago

hestrro commented 1 month ago
    qDebug()<<"First level menu starting point :"<<geometry().bottomLeft();
    menu->setOrigin(geometry().bottomLeft());
    qDebug()<<"The cellRect of the first-level menu with index 0:"<<menu->cellRect(0);

the result: First level menu starting point : QPointF(173.125,30) The cellRect of the first-level menu with index 0: QRectF(0.87868,0.87868 -1.75736x29), You can see that the starting point is QPointF(173.125,30),However, the starting point of the rectangular area of ​​the option with index 0 is different, and the length and width of the rectangle are also abnormal.

hestrro commented 1 month ago

qDebug()<origin(); result: QPointF(-0.87868,0.87868)

uwerat commented 1 month ago

Layout updates are usually done right before the scene graph is updated ( item polishing ). Setting the origin also has no immediate effect on the geometry before.

hestrro commented 1 month ago

So I can’t get the position displayed for each option of the menu, like a point or rectangle like QPointF pos=qskHoverPosition(event);

include "secondmenu.h"

include"QskEvent.h"

include"QskLabelData.h"

SecondMenu::SecondMenu(QQuickItem *parent):QskMenu(parent) { setStrutSizeHint(QskMenu::Icon,QSizeF(20,20)); setPopupFlag(CloseOnPressOutside,true); setPopupFlag(DeleteOnClose,false);

}

void SecondMenu::addMenu(int index, QskMenu *menu) { secondMenu.insert(index,menu); secondMenu[index]->setPopupFlag(CloseOnPressOutside,true); secondMenu[index]->setPopupFlag(DeleteOnClose,false);

secondMenu[index]->setOrigin(mapToScene(this->cellRect(index).topRight()));

 qDebug()<<"二级菜单起点:"<< mapToGlobal(this->cellRect(index).topRight());
 qDebug()<<"一级起点:"<<menu->origin();
 qDebug()<<"一级菜单cellRect:"<<cellRect(index);
qDebug()<<"一级菜单剪辑矩形:"<<clipRect();
 qDebug()<<"一级焦点矩形:"<<focusIndicatorRect();
 qDebug()<<"二级菜单cellRect:"<<secondMenu[index]->cellRect(index);
 qDebug()<<"二级菜单剪辑矩形:"<<secondMenu[index]->clipRect();
 qDebug()<<"二级焦点矩形:"<<secondMenu[index]->focusIndicatorRect();
connect(menu,&QskMenu::triggered,[=]()//选中二级菜单,关闭menu
        {
    this->close();
});

}

void SecondMenu::hoverMoveEvent(QHoverEvent * event) { using A = QskAspect;

setSkinHint( Segment | Hovered | A::Metric | A::Position, qskHoverPosition( event ) );
int index=indexAtPosition(event->position());

QPointF pos=qskHoverPosition( event );
for (QskMenu* menu : secondMenu) {
   int index = secondMenu.indexOf(menu);
    if (menu != nullptr&&!menu->clipRect().contains(pos)&&!cellRect(index).contains(pos)) {

        menu->close();
    }
}
qDebug()<<pos;

if(index>=0&&index<secondMenu.size())
{

    secondMenu[index]->open();

}
update();

}

hestrro commented 1 month ago

二级菜单起点: QPointF(447.121,120.879) 一级起点: QPointF(-0.87868,0.87868) 一级菜单cellRect: QRectF(0.87868,0.87868 -1.75736x29) 一级菜单剪辑矩形: QRectF(0,0 0x0) 一级焦点矩形: QRectF(0,0 0x0) 二级菜单cellRect: QRectF(0.87868,0.87868 -1.75736x29) 二级菜单剪辑矩形: QRectF(0,0 0x0) 二级焦点矩形: QRectF(0,0 0x0)

uwerat commented 1 month ago

Of course you can - but before the layout updates have been done the geometries are not very useful.

You can overload geometryChange ( or geometryChangeEvent ) - both hooks, that are called when position or size of the item has changed.

hestrro commented 1 month ago

Thank you, my problem is solved