Getting the absolute location of a QT widget nested in multiple layouts - qt

I'd like to get the absolute location of a QT widget that is a (horizontal) layout which is itself located in a central widget that has a layout.
I've tried the QWidget::mapToGlobal and QWidget::mapTo but I keep getting (0,0).
Edit
Here's my current implementation
QPoint p( 0 , 0 ); // Recall that widget 'lineEdit' is in a layout, which is itself in a layout
QPoint point = ui.lineEdit->mapToGlobal( p );

"Absolute location" is meaningless.
QWidget::mapToGlobal, as the docs state:-
"Translates the widget coordinate pos to global screen coordinates",
This is not want you want, as you mention in the comments that you're looking for "the position of the widget relative to the top left corner of the window"
You can use the function QWidget::mapTo, but note the following in the documentation:-
The parent must not be 0 and must be a parent of the calling widget.
From the code you've added to the example, it looks like you've used Qt Designer to create and setup the widgets. As you're calling mapToGlobal, there are only two reasons for the mapToGlobal to return (0, 0):-
1) The widget's top left corner is actually at the top left of the screen
2) I suspect you're calling the map functions before the window and its widgets have been displayed on the screen.
Without seeing all your code, I would say that no. 2 is the most likely issue here, so you're calling the mapping functions in something like the constructor of the MainWindow.

Related

Qt: Correct implementation of floating widgets

I've inherited my class from QWidget. Basically no extra code, just changes with the editor.
The way I use it:
focusWidget = new FocusWidget(this); //this points to the mainWindow
focusWidget->show();
focusWidget->hide();
Now the widget appears like this (it now looks ugly because of the bad 4k scaling), at the top left corner of the mainWindow.
I intend to use my application mostly full screen.
Is this usage correct?
How can I make it a floating widget?
If I want multiple widgets like that, how can I control their position?

An image at a specific point in Qt

I am trying to place a .png image(firm logo) at a specific point(coordinate). I've put several buttons, one after another, and now I want the image to be displayed just below these buttons. The code below should do the trick, but the coordinates are simply not working.
//QLabel myLabel; QVBoxLayout *layout; // class members, initialized with 'this'
QPixmap pixmap("v.png");
myLabel.setPixmap(pixmap);
myLabel.setMask(pixmap.mask());
myLabel.setGeometry(QRect(312, 454, 21, 20));
layout->addWidget(&myLabel);
How should I modify the code to simply include this image, possibly at a specific coordinate (just as with QPushButton)? Note that commenting out the last line removes the image, but, even when the image is shown, the buttons cannot be clicked (and they are not part of 'layout') Please provide code that would achieve image positioning with given coordinates.
QLayout is a controller which position widgets added to it. That is why it has no any sense to set coordinates to a widget and then place it to a layout. The layout will change the widget coordinates as soon as the widget is shown.
Futhermore, if you ask how to set certain position in coordinates, you shouldn't use QLayout at all, because it will change any position you set.
QPixmap pixmap("v.png");
myLabel.setPixmap(pixmap);
myLabel.setMask(pixmap.mask());
myLabel.setFixedSize(21, 20);
myLabel.move(312, 452); //ensure that this coordinates are in you widget
myLabel.show();
You will have to either show the label or put it in a layout or make sure it was given a parent in the constructor.
myLabel.setParent(parent_window)
The setParent method might also need you to show.
myLabel.show()
or
layout.addWidget(myLabel)

Qt ScrollArea on widget messes up size and position of widget [Qt 5.1]

I'm new with Qt and I want to implement a scrollable widget which can grow dynamically, e.g. by adding buttons into it when another button is pressed. I try to implement it using the following layout and code:
scrollArea = new QScrollArea(ui->outerWidget);
scrollArea->setWidget(ui->innerWidget);
layout = new QVBoxLayout(ui->outerWidget);
ui->innerWidget->setLayout(layout);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// code for PushButton to add buttons in innerWidget
void MainWindow::on_pushButton_clicked()
{
QPushButton *button = new QPushButton("button"+QString::number( nameCounter ));
nameCounter ++;
ui->innerWidget->layout()->addWidget(button);
}
This implementation has two problems when I run the program, first the innerWidget appears out of place (I define its position in Qt Creator's Design mode) and second after many widgets are added in the layout the scroll bar is doesn't grow, but instead the widgets are become smaller to fit into the layout:
In another thread it was suggested to set widgetResizable to true:
scrollArea->setWidgetResizable(true);
The scroll bar seems to work now but the new problem is that the innerWidget becomes very small so it is barely visible:
So, how can I achieve a scrollable widget that will respect the size and position of the design?
have no environment to verify but good luck.
to place scrollArea the target position,
Manually call SetGeometry, or
Place a QScrollArea in ui form, (suggested if it's static), or
Place a widget in your target position, and set QScrollArea's parent to it, and add QScrollArea to its layout, and Set QScrollArea to be expanding.
manually create a QWidget innerWidget and assign it to scrollArea via QScrollArea::setWidget(*QWidget), try different size policy to innerWidget, such as "Preferred".
Also be aware of Qt's reference mentioned : void QScrollArea::setWidget ( QWidget * widget )
Sets the scroll area's widget.
....
Note that You must add the layout of widget before you call this function; if you add it later, the widget will not be visible - regardless of when you show() the scroll area. In this case, you can also not show() the widget later.
Above list solutions, below are reasons to the problems you mentioned:
scrollArea->setWidget(ui->innerWidget); Setting a widget to ScrollArea will change the parenting and layouting of ui->innerWidget, so the geometry values written in ui form (in Qt Creater) will no longer take effect, this is the reason of innerWidget out of place. ui->innerWidget is no longer a child of outerWidget, it's geometry will follow its new parent (but not scrollArea, there's some tricky layouting inside QScrollArea". To be clear, innerWidget is not helpful to locate scrollArea in such scenario.
In your first clip of code, widget 'scrollArea' is created with parent outerWidget, again no size policy or layout or geometry is specified, so scrollArea will by default be placed at the left top corner of the parent "outerWidget". To place scrollArea to your target geometry, you can " set geometry manually " or " assign innerWidget as scrollArea's parent and expand scrollArea". Obviously the latter method cannot assign ui->innerWiget to scrollArea->setWidget().
scrollArea->setWidgetResizable(true); makes the scrollArea "shrink" at left top corner of outerWidget. This is because, QScrollArea does not increase along with it's contents, it can scroll to display all of it contents so the required size of QScrollArea can be as small as possible. Once the 'Resizable' property is set to "true", QScrollArea decides to shrink to its minimum necessary size, thus the size to display its scroll bar and scroll buttons....

QWidget is not showing up on entire screen

I am a newbie to Qt and facing issue in my application. So here is what I am trying to do.
I have a class with QWidget as parent. This class has a grid layout on it. I set this widget as a central widget to main window. (this thing worked fine though this widget is not centered on Main Window.)
Now I wanted to rotate this widget in 90 degrees so that it can bee shown on device in landscape mode. So I created a graphics view and added this widget to it. (created a scene added widget to that and assigned scene to view.) then this graphics view was rotated and made central widget. this worked amazingly and it was very well centered, looked good on device as well.
But in final integration we want to have all QWidgets so Graphics View is not an option. To tackle this I created a Qwidget member inside my class. applied the layout to it. added this widget to graphicsView and my class was made parent to it.
This also works but has the similar issue I faced in first step, it sits in the top left corner of MainWindow and does not adjust to center. To make things even worse, when deployed on device it was not applied to entire screen. Widget was sitting in some part of top left area and had scroll bars to it! I even tried the set Window State to maximized but had no effect on it.
Here is what I tried
The widget is created inside my class and been added to Graphics View. this view has my class as parent and it will be rotated by using rotate api.
m_gridContainer = new QWidget();
m_gridContainer->setAutoFillBackground(true);
m_gridContainer->setPalette(blackPalette);
m_gridContainer->setLayout(m_grid);
m_gridContainer->setMinimumSize(480,265);
m_scene = new QGraphicsScene(0, 0, 480, 265);
m_window = new QGraphicsView(m_scene,this);
m_scene->setBackgroundBrush(brush);
m_window->setAlignment(Qt::AlignCenter);
m_scene->addWidget(m_gridContainer,Qt::Widget);
To use it from main Window
m_window = new CMyWidget(label, m_txtBox->text());
m_window->getRotatedWidget(90);
setCentralWidget(m_window);
I tried whatever I can but this widget is not being shown full screen (in just a small area) and still have scroll bars to it. I have no idea what exactly is happening there.
m_gridContainer being a graphics item part of a graphics scene, it doesn't receive the resize events of you main window.
You have to handle the resizeEvent() on your CMyWidget and adjust the size of your m_gridContainer accordingly, e.g.
void CMyWidget::resizeEvent ( QResizeEvent * event )
{
m_gridContainer->resize(event->size());
}
BTW, if you are handling the rotation for use on a mobile device, it is managed by Qt itself (by simply resizing your main window). You don't have to do it in your code (you'll actually end up with a widget looking like it has been rotated twice).

Qt QLayout inside QDesktopWidget

I want to do universal method to set position of my widget.
All I wanna get it is set right coordinates for my widget wich must always be in right bottom corner of desktop. My widget can change his height (or maybe width) but it must have adjusted size by both ordinates... (too many words)
My idea is using QDesktopWidget as basic widget to put into my QLayout with stratch items (to align inner (my) widget to right and to bottom sides)
my code prototype is here:
QDesktopWidget * desktopWidget = QApplication::desktop();
MyWidget * myWidget = new MyWidget(desktopWidget);
QVBoxLayout * vlayout = new QVBoxLayout;
vlayout->addStretch();
vlayout->addWidget(myWidget);
QHBoxLayout * hlayout = new QHBoxLayout(desktopWidget);
hlayout->addStretch();
hlayout->addLayout(vlayout);
but it doesn't work...
Help me please implement my idea if you know how.
At this moment I know only one work way to do it - it is manually set pos of widget and handle many events (resize etc.) - but this is not good... (because i do it bad of cause ;-)
)
PS: idea with qlayout inside other widget is working for example with QTextBrowser with sandclock at certer of view, etc.
A QDesktopWidget isn't intended to be used like a typical widget (at least as far as I'm aware, I'm surprised the documentation isn't more explicit about that). So you shouldn't try to parent widgets to it or try to assign it a layout. You call its methods to obtain information about the desktop environment or connect to its signals to be informed of changes.
Using this information, you would then set the geometry of your own application widgets so that they appear on the correct screen and position you want.
This page shows some basic functionality.

Resources