Qt maptoglobal не работает
Summary: In a nutshell, is QWidget::mapToGlobal() supposed to give correct result if the widget is on a [box] layout?
I am using maptoGlobal() to display a popup window off a QPushButton . I want the popup window to appear right where the button is. So I am using just what you would expect:
What I am finding is: when the button is at the lefthand side of window — i.e. pos.x() ==
0 — the global position is good. But as it moves right — pos.x() > 100 etc. — mapToGlobal(pos()) is returning an x() which is getting larger & larger, so the popup appears further & further to the right of the button. The y() however remains correct.
Now, the button is on a QHBoxlayout . I started to read an old post
https://www.qtcentre.org/threads/40574-mapToGlobal-mapFromGlobal-isn-t-working-properly
which said at one point
So it is managed by a layout which might explain why your own geometry management fails. If you wish to do your own moving/resizing, you can’t use layouts at the same time.
Is that what is going on?
Please don’t ask me to repro a full example for now, it will take too long. I would just like to quickly know: if I place a widget on a layout, does that mean I won’t be able to use mapToGlobal(pos()) to get the correct global screen coordinate to position a popup at? If so, how can I map from a widget on a layout to its correct screen position? Thanks.
That’s wrong. pos() is a position in the parent, and this->mapToGlobal maps it relatively to this, not the parent, so simply said — you’re mixing different coordinate systems — local and parent. Additionally, in case of a top level widget that has no parent, pos() is already a global position.
If you want the global position of the button you either map its position in parent relative to that parent:
or, simpler, and IMO more appropriate here, just map the upper left corner of your button relative to it:
@JonB I can reproduce it:
That’s wrong. pos() is a position in the parent, and this->mapToGlobal maps it relatively to this, not the parent, so simply said — you’re mixing different coordinate systems — local and parent. Additionally, in case of a top level widget that has no parent, pos() is already a global position.
If you want the global position of the button you either map its position in parent relative to that parent:
or, simpler, and IMO more appropriate here, just map the upper left corner of your button relative to it:
@Chris-Kawa +1 that explains so much of my past experience 🤦♂️
with that in mind, this works now as well:
Thank you both for prompt responses!
Additionally, in case of a top level widget that has no parent, pos() is already a global position.
I’m a little lost here. I am trying to get the button’s coordinates, the button does have parentage. It is the popup which will not have parentage, and so need global coordinates.
Meanwhile, I am about to try out your solutions and will report back.
UPDATE
Still not sure what you meant by
That’s what I had originally ( this == btn ); I think you meant that if it had no parent? [EDIT No, see below]
Anyway, altered to
and lo & behold the global position is correct, whether the button is at left or right of its parent/layout.
You are an genius, thank you! 🙂
EDIT
OIC, btn->mapToGlobal(QPoint(0,0)) , that’s QPoint(0, 0) not btn->pos() . Got it! So now I have:
Источник
Thread: mapToGlobal/mapFromGlobal isn’t working properly
Thread Tools
Search Thread
Display
mapToGlobal/mapFromGlobal isn’t working properly
I am using Qt 4.7 and have come across an interesting problem with positioning widgets using QWidget::mapToGlobal() and QWidget::mapFromGlobal().
I have a button (in a dock bar) that displays a widget as a popup. I am trying to position the popup relative to the button in different ways depending on where the button is on the screen (since it is in a dock bar the user can move it around).
My method for positioning the popup takes a widget to use as the widget to position the popup on. I then get the global coordinates of this widget and the width and height of the popup widget to determine the correct position of the popup.
What is interesting is that the coordinates for mapToGlobal() and mapFromGlobal are only returning the correct results when in the bottom-right corner of the screen. The other three coordinates return incorrect results and the popup does not display in the correct spot.
Here is the code for positioning our popup:
Are we doing something wrong here? I’ve had two other guys look at this code and we’ve already spent 3 days trying to figure this out.
Any tips, pointers, suggestions, would be greatly appreciated
Re: mapToGlobal/mapFromGlobal isn’t working properly
Does getUIPopUp() create the widget or does it simply return it? Was the widget visible on the screen prior to running mapToGlobal()? What does the following print?
Are the values what you expect? What is the purpose of the do-while loop?
Your biological and technological distinctiveness will be added to our own. Resistance is futile.
Please ask Qt related questions on the forum and not using private messages or visitor messages.
Re: mapToGlobal/mapFromGlobal isn’t working properly
Thanks for the quick reply! Here are the answers to your questions:
- getUIPopUp() simply returns the widget. It is created previously
- The call to processEvents() ensures that the widget is visible before moving it
- The posWgt that is passed in is guaranteed to only live within in a dockbar. The do while loop goes through the parents until it finds a parent that has an orientation (the dock bar). The positioning changes based on the orientation of the dock bar.
- I’m getting results that I would not expect from the debug code that you gave me. See below for details.
I placed the debug code just before moving popupWgt and just after moving popupWgt. I ran two test cases, one with posWgt being in the Bottom-Right corner (this works) and one with posWgt being in the Top-Left corner (this doesn’t work). However, In both cases I’m getting results that I didn’t expect.
Before setGeometry() or move()
- getUIPopup()->geometry() //(805, 280, 310×521)
- getUIPopup()->window()->geometry() //(805, 280, 310×521)
After setGeometry() or move()
- getUIPopup()->geometry() //(1524, 456, 314×566)
- getUIPopup()->window()->geometry() //(1524, 456, 314×566)
There are two things that are confusing me:
- The width and height changes after the move
- The new x,y coordinates are not offset by the values of popPnt: (723, 221)
Before setGeometry() or move()
- getUIPopup()->geometry() //(805, 280, 310×521)
- getUIPopup()->window()->geometry() //(805, 280, 310×521)
After setGeometry() or move()
- getUIPopup()->geometry() //(736, 74, 314×566)
- getUIPopup()->window()->geometry() //(736, 74, 314×566)
There are two things that are confusing me:
- The width and height changes after the move
- The new x,y coordinates are not offset by the values of popPnt: (-65, -161)
Источник
Qt maptoglobal не работает
Ктото может что либо внятного объяснить по поводу семейства методов:
QWidget::mapToGlobal(QPoint)
QWidget::mapToParent(QPoint)
QWidget::mapTo(QPoint)
QWidget::mapFromGlobal(QPoint)
QWidget::mapFromParent(QPoint)
QWidget::mapFrom(QPoint)
1) ну это же какой то бред, то что они делают. Ничего не работает.
2) зачем у методов параметр QPoint? если мне нужно транслировать координаты виджета в координаты экрана, разумеется что я буду именно у него этот метод и дергать и использовать именно его координаты. Зачем еще параметр?
3) как ими вообще пользоваться?
4) простое: есть диалог, на нем кнопка. мне надо чтото нарисовать на или рядом с кнопкой. У кнопки есть
QPoint p = mybutton->pos();
пытаюсь чтото вывести по этим координатам, а оно вообще в другом углу рисуется. Понятно, что видимо весь секрет в тех методах, но к сожалению всё перепробовал, они не работают, и нифига не документировано.
5) зачем все эти переводы из чего то во чтото? думаю было бы намного проще:
QPoint p = mybutton->ХочуКоординатыНеважноОтносительноЧего(); // просто хочу координаты чтобы там чтото нарисовать
| | От: | AlexGin |
| Дата: | 31.03.16 09:32 | |
| Оценка: |
Здравствуйте, уважаемый Мёртвый Даун, Вы писали:
.
Насчёт применения mapToGlobal — я использую его для отображения контекстного меню:
| | От: | Мёртвый Даун |
| Дата: | 31.03.16 10:19 | |
| Оценка: |
Здравствуйте, AlexGin, Вы писали:
AG>Здравствуйте, уважаемый Мёртвый Даун, Вы писали:
AG>.
AG>Насчёт применения mapToGlobal — я использую его для отображения контекстного меню:
Да в том то и дело, с контекстными меню никаких проблем и нет.
| | От: | Chorkov |
| Дата: | 31.03.16 10:25 | |
| Оценка: | 18 (2) +4 | |
Здравствуйте, Мёртвый Даун, Вы писали:
МД>Всем привет!
МД>Ктото может что либо внятного объяснить по поводу семейства методов:
МД>QWidget::mapToGlobal(QPoint)
МД>QWidget::mapToParent(QPoint)
МД>QWidget::mapTo(QPoint)
МД>QWidget::mapFromGlobal(QPoint)
МД>QWidget::mapFromParent(QPoint)
МД>QWidget::mapFrom(QPoint)
Посмотри картинку по этой ссылке:
http://doc.qt.io/qt-4.8/application-windows.html#window-geometry
На этой картинке:
зеленые методы (x(), y(), frameGeometry(), pos(), move()) — в системе координат родительского виджета,
фиолетовыфе (geometry(), width(), height(), rect(), size())- в системе координат текущего виджета (у которого запрошены).
Так проще всего двигать дочерние виджеты относительно родителя.
МД>1) ну это же какой то бред, то что они делают. Ничего не работает.
МД>2) зачем у методов параметр QPoint? если мне нужно транслировать координаты виджета в координаты экрана, разумеется что я буду именно у него этот метод и дергать и использовать именно его координаты. Зачем еще параметр?
МД>3) как ими вообще пользоваться?
МД>4) простое: есть диалог, на нем кнопка. мне надо чтото нарисовать на или рядом с кнопкой. У кнопки есть
МД>QPoint p = mybutton->pos();
попробуй:
QPoint p = this->mapFrom( mybutton->parentWidget(), mybutton->pos() );
(если тебе надо рисовать в координатах this.)
Если не получилось — приведи полный код своего примера.
МД>пытаюсь чтото вывести по этим координатам, а оно вообще в другом углу рисуется. Понятно, что видимо весь секрет в тех методах, но к сожалению всё перепробовал, они не работают, и нифига не документировано.
МД>5) зачем все эти переводы из чего то во чтото? думаю было бы намного проще:
МД>QPoint p = mybutton->ХочуКоординатыНеважноОтносительноЧего(); // просто хочу координаты чтобы там чтото нарисовать
| | От: | Мёртвый Даун |
| Дата: | 31.03.16 11:19 | |
| Оценка: | -5 | |
Здравствуйте, Chorkov, Вы писали:
C>Посмотри картинку по этой ссылке:
C>http://doc.qt.io/qt-4.8/application-windows.html#window-geometry
C>На этой картинке:
C> зеленые методы (x(), y(), frameGeometry(), pos(), move()) — в системе координат родительского виджета,
C> фиолетовыфе (geometry(), width(), height(), rect(), size())- в системе координат текущего виджета (у которого запрошены).
C>Так проще всего двигать дочерние виджеты относительно родителя.
Это вообще какое то зло! У меня есть только экран, и следовательно его координаты. Всё остальное — не нужно.
Нет, всё равно там ничего не работает, впрочем как и всё всегда в Qt.
Диалоговое окно, с кнопкой. Кнопка где-то произвольно на диалоге лежит. Мне надо показать message box рядом с кнопкой.
Что за огород надо городить с какими то переводами координат? Ну естессно нужны экранные! Экранные. Долбанное Qt. Всегда нужны экранные! Одни, единственные!
Почему: mybutton->pos() возвращает всегда QPoint(0, 0) . Кто это всё проектировал в Qt? Надеюсь он уже прокрутил пальцы через мясорубку?
mybutton->mapToGlobal(mybutton->pos()); // вообще бред возвращает. но другие методы этого семейства вообще ничего не возвращают.
Как это сделать? Ну почему всегда возникают проблемы на пустом месте в этом сраном Qt.
Ок, подскажи плиз, как мне узнать координаты хоть чего то в окне, чтобы чтото показать по этим координатам? Оно ничего не работает.
Короче хрень полная.
Опустимся до самого элементарного вопроса:
Кнопка на диалоге. Диалог по середине экрана. Так, что кнопка тоже ровно по середине экрана. Я хочу следующее:
(Псевдокод)
QPoint p = mybutton->pos(); // ВОТ ЗДЕСЬ p ДОЛЖЕН ЖЕЛЕЗОБЕТОННО БЫТЬ QPoint(screen.width/2, screen.height/2)
Какие действия для этого надо проделать? Что может быть проще. Жесть.
Источник