Reputation: 2658
Environment:
Issue:
I have a mainwindow. In it, some container levels down, is a gui element cb_B_8
, a button. I can get that element's position and size this way, and it comes to me precisely relative to the mainwindow area under its titlebar (theParent
is the mainwindow instance):
QPoint buttpos = theParent->ui->cb_B_8->pos(); // = 473,576
QRect butrect = theParent->ui->cb_B_8->rect(); // = 0,0,32,26
That makes perfect sense to me.
So now I open a dialog this way:
void MainWindow::mybandersnatch(int i)
{
setband *tt;
tt = new setband(this,i);
tt->show();
tt->raise();
}
}
The dialog starts like this:
setband::setband(QWidget *parent, int bindex) :
QDialog(parent),
ui(new Ui::setband)
{
theParent = parent; // dialog local copy of parent
...
It opens in the center of my mainwindow (theParent
)
I want to re-position this dialog so that the top of the dialog window is directly under the lower edge of the button.
I have been unable to retrieve the dialog's position relative to the window that is its parent; and I have also been unable to position the dialog relative to that window. I have tried a few things that seemed likely but have come up empty.
Conceptually, considering I have the button's position relative to the window, if I had the dialog's position relative to the window, and could likewise set it relative to the window, I want to set it exactly this way:
newDialogYpos = button.yPos + button.yHeight; // below button
buttonXcenter = button.xPos + (button.width / 2);
dialogHalfWidth = dialog.width / 2;
newDialogXpos = buttonXcenter - dialogHalfWidth;
One slight twist to this is it has to work on multi-display computers. Seems like some of the positioning is relative to the main display, which is pathological for my needs - the dialog has to end up relative to the app, not the main display. I've tried these things to get positions, and come up dry:
t = this->rect(); // = 0,0 410x320 (dialog)
dp = this->pos(); // = 0,0 (dialog)
ap = QApplication::desktop()->screen()->pos(); // = 0,0 ?
mtp = this->window()->mapFromParent(tmw->pos()); // = 0,0 ?
// main display is 1680x1050, app is not on this display
// this display is 1280x1024 (I have 8 displays on this machine)
// this display is immediately to the right of the main display
// app window is fullscreen, so at top left of 1280x1024 display
// this result seems to incorporate other display positions + widths:
// ------------------------------------------------------------------
w = QApplication::desktop()->screen()->rect(); // = 0,0 3080x1050
Appreciate any insight.
Upvotes: 1
Views: 4417
Reputation: 2658
So, I got everything I was asking figured out, although apparently the Qt get titlebar height method is broken. The following works on all of the eight displays in my system:
void setband::positionDialog()
{
QPoint mw; // mainwindow position
QPoint bp; // button position
QRect r; // button rect
QRect d; // dialog rect
QPoint sp; // target position of all this
QPoint addend; // the delta required to move from dialog position
int tbh; // titlebar height (qt returns 0 for this, sigh)
bp = theParent->ui->cb_B_11->pos(); // = 473,576
mw = theParent->pos(); // = 1600,0
d = this->rect(); // = 0,0 410x320 (dialog)
r = theParent->ui->cb_B_11->rect(); // = 0,0 32,26
addend.setX(-((d.width() / 2) - (r.width() / 2))); // position dialog centered on X re button
// tbh = QApplication::style()->pixelMetric(QStyle::PM_TitleBarHeight); // get title bar height returns 0?!?
tbh = 25; // use bloody guesswork, then
addend.setY(tbh + r.height()); // need to move past button pos+height+titlebarHeight
sp = mw + bp + addend; // combine all this
this->move(sp); // and move
}
Upvotes: 1
Reputation: 5207
The pos
of a widget inside another is in the coordinate system of its parent.
You need to use the parent's mapToGlobal()
to get screen coordinates.
Upvotes: 0