PDA

View Full Version : How to get QMainWindow position



sh_erfan
14th August 2015, 18:33
Hello
I am new to Qt
I have written a simple application and I want to get current position of the QMainWindow.
this is my code:



M::M(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::M)
{
ui->setupUi(this);
QMessageBox msg;
msg.setText(QString::number("what returns the X or Y of the window?"));
msg.exec();
}


I searched a lot. There where topics about setting the position, not getting it.
I also tried geometry().x(), but it always returns 0 !!!
Please help me. I need this.
Best regards...

prasad_N
14th August 2015, 20:50
QWidget::mapToGlobal()

ars
14th August 2015, 21:35
Hello,

you ask too early for the window position (in the CTOR). Try overriding QMainWindow::moveEvent() and print the result of geometry() inside this function. You observe that moveEvent() gets called multiple times even without manually moving the window around.

Here is a code snippet:

void MainWindow::moveEvent(QMoveEvent *e)
{
QMainWindow::moveEvent(e);
QRect r = geometry();
std::cout << "moveEvent: ";
std::cout << "x = " << r.x() << ", y = " << r.y() << ", width = " << r.width() << ", height = " << r.height() << std::endl;
}

Running the application produces the following output:


CTOR: x = 0, y = 0, width = 400, height = 300
moveEvent: x = 0, y = 0, width = 400, height = 300
moveEvent: x = 808, y = 23, width = 400, height = 300

The line with CTOR shows the coordinates received when calling geometry in the contructor. Note that there are two calls to moveEvent().

You may also look at frameGeometry() and pos() methods. See http://doc.qt.io/qt-5.4/application-windows.html#window-geometry for details.

Best regards
ars

d_stranz
14th August 2015, 23:09
You could also override showEvent(), which is called only once when the window is first shown (and in the final position, unlike moveEvent()). If you need to know where the window is at all times, then you'll need moveEvent() as well, but only need to remember the position at the last time it is called. If the window is moved manually by the user, there will be a moveEvent for every small change of the position.

ars
15th August 2015, 09:26
@d_stranz: Overriding showEvent() was my first attempt, but it did not show the expected result. Adding showEvent() override, I get the following output when running the application:


moveEvent: x = 0, y = 0, width = 400, height = 300
showEvent: x = 0, y = 0, width = 400, height = 300
moveEvent: x = 404, y = 23, width = 400, height = 300

However, if I explicitly set the window position in the CTOR by


QRect r = geometry();
r.setX(100); r.setY(100);
setGeometry(r);

the output changes to


moveEvent: x = 100, y = 100, width = 300, height = 200
showEvent: x = 100, y = 100, width = 300, height = 200


For me it looks like the last moveEvent in the first example gets triggered by the window manager, which moves the window to a position where it is visible including the title bar.

Moving the window around gives me a moveEvent notification when I drop the window at the final position. I only get one additional moveEvent.

The testing above was done using Qt 5.4.1 on OpenSuse 13.2.

Next I ran the same program under Windows 7 with Qt 4.7. Here things change. Without explicit setting of geometry I get a single moveEvent and a single showEvent call both showing the same window position. When I now move the window around with the mouse, I get moveEvent updates on every small change of position.

Best regards
ars

sh_erfan
15th August 2015, 15:39
Honestly I didn't get how to achieve this using QWidget::mapToGlobal(QPoint). I think this can be very straight forward but I would be glad if you say a short example with it.


QWidget::mapToGlobal()

Honestly I didn't get how to achieve this using QWidget::mapToGlobal(QPoint). I think this can be very straight forward but I would be glad if you say a short example with it.

Added after 9 minutes:

Thanks to all :)
I used all replies to find the solution.
actually I want to read position at start time from file, If file not exist, I set it to an arbitrary position like (50,50). When closing, I write current position to the file to get it next time and show the window in prev position. I use closeEvent to achieve this. The reason I get the correct position is that setGeometry() is called at start up, even if the file not exist.
this is the code:



M::M(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::M)
{
ui->setupUi(this);

if(QFile::exists("c.ccf"))
{
QFile f("c.ccf");
f.open(QIODevice::ReadOnly);
QString str = f.readAll();
f.close();

QStringList lst = str.split(",");
int x = QString(lst.at(0)).toInt(), y = QString(lst.at(1)).toInt();

QRect r = geometry();
r.setX(x);
r.setY(y);
setGeometry(r);
}
else
{
QFile f("c.ccf");
f.open(QIODevice::WriteOnly);
f.close();

QRect r = geometry();
r.setX(50); r.setY(50);
setGeometry(r);
}
}

void M::closeEvent(QCloseEvent *e)
{
QRect r = geometry();

QFile f("c.ccf");
f.open(QIODevice::WriteOnly);
QTextStream out(&f);
out << QString::number(r.x()) + "," + QString::number(r.y()) << endl;
f.close();
}

prasad_N
16th August 2015, 10:17
Honestly I didn't get how to achieve this using QWidget::mapToGlobal(QPoint). I think this can be very straight forward but I would be glad if you say a short example with it.
[/CODE]

Sorry I misunderstand your question, i thought you are asking for Screen positions w.r.t window.



int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

qDebug() << "Pos = " << w.mapToGlobal(w.pos()); // will give you screen position w.r.t main window.

return a.exec();
}