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:
Qt Code:
  1. void DzMainWindow::positionUIPopUp( QWidget* posWgt )
  2. {
  3. if(!posWgt)
  4. return;
  5.  
  6. DzUIPopUpWgt* popupWgt = getUIPopUp();
  7.  
  8. if(!popupWgt)
  9. return;
  10.  
  11. dzApp->processEvents();
  12.  
  13. // Find a parent widget that has an orientation
  14. Qt::Orientation orient = Qt::Horizontal;
  15. if(QWidget* parentWgt = posWgt->parentWidget())
  16. {
  17. do
  18. {
  19. QVariant data = parentWgt->property("orientation");
  20. if(data.isValid())
  21. {
  22. orient = Qt::Orientation(data.value<int>());
  23. break;
  24. }
  25. parentWgt = parentWgt->parentWidget();
  26. } while (parentWgt);
  27. }
  28.  
  29. QPoint posWgtGlobalPos = posWgt->mapToGlobal(QPoint(0,0));
  30.  
  31. // Split screen into quadrants
  32. QDesktopWidget *desktop = QApplication::desktop();
  33. QRect screenRect = desktop->availableGeometry(posWgtGlobalPos);
  34.  
  35. int screenMidX = screenRect.x() + (screenRect.width() / 2);
  36. int screenMidY = screenRect.y() + (screenRect.height() / 2);
  37.  
  38. QRect topLeft = screenRect;
  39. topLeft.setRight(screenMidX);
  40. topLeft.setBottom(screenMidY);
  41.  
  42. QRect topRight = screenRect;
  43. topRight.setLeft(screenMidX);
  44. topRight.setBottom(screenMidY);
  45.  
  46. QRect bottomLeft = screenRect;
  47. bottomLeft.setRight(screenMidX);
  48. bottomLeft.setTop(screenMidY);
  49.  
  50. QRect bottomRight = screenRect;
  51. bottomRight.setLeft(screenMidX);
  52. bottomRight.setTop(screenMidY);
  53.  
  54. // Position the popup widget based on the quadrant posWgt is in
  55. int popX = posWgtGlobalPos.x();
  56. int popY = posWgtGlobalPos.y();
  57.  
  58. if(topLeft.contains( posWgtGlobalPos ))
  59. {
  60. if (orient == Qt::Horizontal)
  61. {
  62. popY += posWgt->height();
  63. }
  64. else
  65. {
  66. popX += posWgt->width();
  67. }
  68. }
  69. else if(topRight.contains( posWgtGlobalPos ))
  70. {
  71. popX -= popupWgt->width();
  72.  
  73. if (orient == Qt::Horizontal)
  74. {
  75. popX += posWgt->width();
  76. popY += posWgt->height();
  77. }
  78. }
  79. else if(bottomRight.contains( posWgtGlobalPos ))
  80. {
  81. popX -= popupWgt->width();
  82. popY -= popupWgt->height();
  83.  
  84. if (orient == Qt::Horizontal)
  85. {
  86. popX += posWgt->width();
  87. }
  88. else
  89. {
  90. popY += posWgt->height();
  91. }
  92. }
  93. else if(bottomLeft.contains( posWgtGlobalPos ))
  94. {
  95. popY -= popupWgt->height();
  96.  
  97. if (orient == Qt::Vertical)
  98. {
  99. popX += posWgt->width();
  100. popY += posWgt->height();
  101. }
  102. }
  103.  
  104. QPoint popPnt = popupWgt->mapFromGlobal(QPoint(popX, popY));
  105. popupWgt->setGeometry(
  106. popupWgt->x() + popPnt.x(),
  107. popupWgt->y() + popPnt.y(),
  108. popupWgt->width(),
  109. popupWgt->height());
  110.  
  111. //popupWgt->move(popupWgt->x() + popPnt.x(), popupWgt->y() + popPnt.y());
  112. }
To copy to clipboard, switch view to plain text mode 

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