Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Global position of Rectangle



  • Hi.

    I have a simple, but somehow "ungoogable", question.

    I have a Rectangle and a Window (QtQuick.Window 2.0)

    When you click on the rectangle a window should appear beneath the rectangle

    How do I get the "global position (x, y)" of the rectangle so I can position the window beneath it? As the window is not an Item you cannot use the "mapFromItem() or mapToItem()" functions!



  • Hi,

    You could use mouse area properties.
    mouseX and mouseY delivers the current mouse position.



  • Thanks for your reply, but as stated in the "documentation":http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-mousearea.html#mouseX-prop:
    "The coordinates are relative to the MouseArea."

    P.s. been on holiday, hence my slow reply - sorry.


  • Moderators

    Hi,

    I think you will get to access those functions from cpp class from where your QML gets called .
    For e.g in Qt Quick 2.0 from QtQuick2ApplicationViewer class



  • Maybe.

    However, I think that it would require that the rectangle is within the main window.
    I, unfortunately, open a new window via QML and it is within this window my problem sits. Maybe I need to do a "Qt hack" and create the window from c++ and hide it until needed. I should then be able to get the coordinates of that window and from there calculate the rectangle position?


  • Moderators

    Yes. Maybe. Can you post your QML code ? And also how it is called ?



  • Yes. I've tried to limit the code for simplification :)
    Inside the "SettingsSection" is where I try to open another "dropdown window". Here, however, I cannot get the global position of the rectangle resided inside a "SettingsSection" (a "SettingsSection" is just a rectangle with images, buttons etc.)

    I think I might have to give up the idea of using the QtQuick.Window for the ComboBox, and then just let the rectangle grow (will loose the shadow and have to battle with z order (guess I can set in in an onclick event))

    Notes:

    • The widget window is a wrapper made due old code base that this code will eventually be moved to
    • I cannot use Qt's ComboBox and style it, as you cannot style the list (so the "button" is nice, but the dropdown is the ugliest thing mankind have yet seen)

    Main.cpp
    @#include <QApplication>
    #include "widgetwindow.h"

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    WidgetWindow toolbarContainer;
    toolbarContainer.show();
    
    return a.exec&#40;&#41;;
    

    }@

    WidgetWindow.cpp
    @#include <QHBoxLayout>
    #include <QMargins>

    #include <QQuickItem>
    #include <QtQuick/QQuickView>

    WidgetWindow::WidgetWindow(QWidget *parent) :
    QWidget(parent)
    {
    initWindow();

    //Load the qml file into a QWidget
    QQuickView *view = new QQuickView();
    QWidget *container = QWidget::createWindowContainer(view, this);
    container->resize(500, 50);
    container->setFocusPolicy(Qt::TabFocus);
    view->setSource(QUrl::fromLocalFile&#40;"..\\..\\ITW_Toolbar\\QML\\Toolbar\\Toolbar.qml"&#41;);
    
    //Use the BoxLayout to make the qml fill the form
    QHBoxLayout *layout = new QHBoxLayout;
    layout->setSpacing(0);
    layout->setMargin(0);
    layout->addWidget(container);
    
    //Get the width of the screen
    int screenWidth = getScreenWidth();
    
    //Set the layout, move (include frame)
    this->setLayout(layout);
    this->move(0 + (this->x() - this->geometry().x()), 0 + (this->y() - this->geometry().y()) );
    
    //resize the form (Qt HACK with resizing for redraw)
    this->resize(screenWidth, 40);
    QObject *rootObject = dynamic_cast<QObject*>(view->rootObject());
    rootObject->setProperty("width", screenWidth);
    
    //Signals
    connectQmlSignals(view);
    

    }@

    Toolbar.QML
    @Rectangle
    {
    id: itwToolbar
    width: Screen.desktopAvailableWidth
    height: 42
    color: "white"

    signal quit;
    
    Flow
    {
        id: buttonContainer
        anchors.verticalCenter: parent.verticalCenter
        anchors.horizontalCenter: parent.horizontalCenter
        spacing: 10
    
        ...
    }
    
    //The settings window that is a QtQuick.Window 2.0 (opens like a drop-down beneath the toolbar (centered)
    SettingsComponents.SettingsWindow {
        id: settingsWindow
        x: (buttonContainer.x + (buttonContainer.width / 2)) - (settingsWindow.width / 2)
        y: itwToolbar.height
    }
    

    }@

    SettingsWindow.QML
    @DropDownWindow {
    openedHeight: 400
    width: 500
    color: "white"
    ...

    //
    //Profile section
    //
    SettingsHeader {
        ...
    }
    
    SettingsSection {
        ...
    }
    
    SettingsSection {
        ...
    }
    
    //
    //Reader section
    //
    SettingsHeader {
        ...
    }
    
    SettingsSection {
        ...
    }
    
    SettingsSection {
        ...
    }
    
    ...@
    

    DropDownWindow.QML
    @import QtQuick 2.0
    import QtQuick.Controls 1.0
    import QtQuick.Window 2.0

    Window {
    id: dropDownWindow
    width: 100
    height: 400//dropDownWindow.childrenRect.height + 6

    property int openedHeight: 100
    
    visible: false
    flags: Qt.Popup | Qt.WindowStaysOnTopHint
    
    Behavior on height { NumberAnimation { id: heightAnimation; easing.type: Easing.OutQuad; duration: 400 } }
    
    function hide()
    {
        height = 0;
    }
    
    function show()
    {
        height = openedHeight;
    }
    
    Rectangle {
        id: borderRect
        color: "white"
        anchors.fill: parent        
    
        border.color: "black"
        border.width: 1
    

    }@

    SettingsSection.QML
    @Rectangle {
    id: sectionRect
    ...

    Windows8_ComboBox {
        id: sectionSelectionComboBox
        ...
    }
    

    }@
    Windows8_ComboBox
    @import QtQuick 2.0

    Rectangle {
    height: 25
    width: 100
    color: "white"

    border {
        color: "lightgray"
        width: 1
    }
    
    property string currentSelection: "select"
    
    Text{
        ...
    }
    
    Image{
        ...
    }
    
    MouseArea{
        anchors.fill: parent
        hoverEnabled: true
        onEntered: parent.color = "lightblue"
        onExited: parent.color = "white"
        onClicked: {            
                dropDownList.height == dropDownList.openedHeight ? dropDownList.hide() : dropDownList.show()
        }
    }
    
    DropDownWindow {
        id: dropDownList
        width: parent.width
        height: 100
        openedHeight: 100
    
        visible: false
    }
    
    Component.onCompleted:
    {
        //What to do?
        dropDownList.x = x
        dropDownList.y = height
    }
    

    }@


  • Moderators

    Hi,

    As far as i understand from your code is you want to show a window like a dropdown when you click "Windows8_ComboBox" item. Is it so ? So can't you use "anchors.top" property and anchor it to bottom of "Windows8_ComboBox" ? In this way it will move along as the width of main window also increases.



  • Yes, that is correct. I am making my own dropdown/combobox implementation as the one in Qt is not Windows 8 like.

    Anchors is not a part of a QtQuick.Window so that is, unfortunately, not an option...


  • Moderators

    Yes. If you are not using QtQuick.Window ofcourse.
    A better option would be a ListView in your case as it will be scrollable if you have more items in it.



  • Yes. I'm also thinking of going for the ListView or some other form. However this will have the disadvantage that the list will not show outside the parent and that I have to fix the z-order issue when having multiple controlls... the latter should be manageable.


Log in to reply