Moving QMainWindow does not affect where the child widgets are being drawn - c++

I'm pretty new to the Qt environment. I have an application that I want to display on a second monitor. Currently, in the MainWindow constructor, I'm moving the window to a second monitor using the following code.
main():
MainWindow w;
w.showFullScreen();
MainWindow() constructor:
QRect screenres = QApplication::desktop()->screenGeometry(1);
this->move(QPoint(screenres.x(), screenres.y()));
this->resize(screenres.width(), screenres.height());
This works for my main window. The problem is that all the children widgets still get displayed on the first monitor. I have a menu widget that is part of the centralWidgetFrame that gets created in the constructor after the move(), but it doesn't get created on the second monitor. From my understanding, the child widgets should be created in positions relative to their parent.
The MainWindow returns a pos() of (1920,0) as expected and the child menu widget gives me a pos() of (0,0).
I'm using Qt 4.7.1. Any suggestions?

I think this is because you're moving and resizing the MainWindow in its constructor.
Do it in main():
MainWindow w;
QRect screenres = QApplication::desktop()->screenGeometry(1);
w.move(QPoint(screenres.x(), screenres.y()));
w.resize(screenres.width(), screenres.height());
w.showFullScreen();

Related

Qt 'glue' two widgets together

I have two widgets (both QFrames), none of them have any title bar associated with them (which I achieve through setWindowFlags(Qt::FramelessWindowHint)). One of them is a main widget, and the other a sidebar sort of widget, which is supposed to stick to it at its right boundary (its height being approximately 1/4th of the main widget).
I cannot keep them both in a transparent QFrame with static positioning, since the main widget is draggable through its top (since title bar is missing on it, I do it manually by intercepting mousepress/mousemove events and moving it accordingly). The custom drag on the main widget works fine, but when I try to move the sidebar along with, a very obvious visual delay shows up between the two, there are momentary gaps visible between the two while dragging the main widget to the left, or momentary overlapping between the two when dragging the main widget to the right (the sidebar is not draggable, no drag logic is implemented for it).
How do I 'glue' these two widgets together, such that they move together all the time without any delay? I browsed the Qt docs, it may be possible that QDockWidget can help here, but I could not understand how. The main widget here is not a QMainWindow.
Platform - OS X Yosemite, Qt 5.3.1, 32 bit.
You should definitely use QDockWidget here.
Make your "main widget" derive from QMainWindow rather than QFrame (it may not be "obvious" as QMainWindow does not derive from QFrame, but it should not be such a big deal).
Then, encapsulate your second widget within a QDockWidget and dock it in the main widget like that:
// secondWidget being your QFrame based widget
// mainWidget being your "main widget"
QDockWidget* dockingBar = new QDockWidget("My bar", mainWidget );
dockingBar->setWidget( secondWidget );
// dock on left side, change first parameter to dock somewhere else:
mainWidget->addDockWidget( Qt::LeftDockWidgetArea, dockingBar );
An alternative is to create a third widget that would become your top-level widget and use a QLayout to insert your two QFrames in this new one:
QWidget* newTopLevelWidget = new QWidget();
// QHBoxLayout to have mainWidget on the left hand side of secondWidget
// Replace by QVBoxLayout to have mainWidget on top of secondWidget
QLayout* layout = new QHBoxLayout( newTopLevelWidget );
layout->addWidget( mainWidget );
layout->addWidget( secondWidget );

Qt QWidget::setGeomerty

i'm stuck with a simple Function of Qt that does not work for me.i made a class that inherits
from QMainWindow and another class that inherits from QWidget.then i made from the second a member object(a pointer to) inside the first and assigned it as its centralWidget during the construction of my window.
when it comes to adjust my centraWidget inside the window with the function QWidget::setGeomerty() it simply don't work.here's my code:
void MainWindow::show()
{
//some code that centers my window on the screen
int margin=this->width()/7;
centralWidget()->setGeometry(margin,centralWidget()->geometry().top(),this->width()-margin,centralWidget()->geometry().bottom());
QMainWindow::show();
}
i know it might be stupid but i just can't figure it out.help me.
QMainWindow has its own layout in which the center area is occupied by the central widget. So it won't be pretty straightforward to break that layout and modify the central widget size / position arbitrarily.
What I recommend is to use a placeholder central widget and add your widget as a child.
I'm pretty sure you can achieve what you want by setting a proper Qt built in layout to the "placeholder" central widget and then adding your widget to the layout.
layouts was necessary to manage what i want; i think it's not possible to hand directly over the central widget and try to move/resize it;but by adding a layout and a child widget, we can dispose of them.here is my code:
mainwindow.cpp
// i focused on my window constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_MainView(new MainView(this)),
m_WindowLayout(new MainWindLayout(NULL))//my custom layout witch just inherits from QGridLayout
{
//.............
setCentralWidget(m_MainView);
m_WindowLayout=new MainWindLayout(m_MainView);//my layout set into my central Widget"m_MainView".
QWidget *temp(dynamic_cast<QWidget *>(m_MainView->centralView()));//centralView() returns a child QWidget of my central Widget
QMargins margins(this->width()/5,0,this->width()/5,0);//setting up layout margins :left,top,right,bottom;exactly what i need
m_WindowLayout->setContentsMargins( margins);
m_WindowLayout->addWidget(temp,0,0,-1,-1);//adding my child widget to the layout filling all cells of the gridlayout.
}
thanks everybody

Qt: How does parenting affect the layout of children widgets?

I've been trying to learn Qt for the purposes of embedding a GUI on top of my OpenGL projects. In this case, the idea is to have my OpenGL viewport fill my main window. I have a simple QtWidget-based GUI that contains a 'RenderSurface' which is a subclass of QGLWidget. However, I've noticed that making my RenderSurface a child of my MainWindow has unwanted effects on my GUI's layout.
Here's the simple MainWindow code and screen shot without use of parenting:
#include "mainwindow.h"
#include "rendersurface.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
renderSurface()
{
setCentralWidget(&renderSurface);
setWindowTitle("QtGL Test");
}
MainWindow::~MainWindow()
{
}
In this case, my RenderSurface (QGLWidget subclass) is not passed a pointer to any parent QWidget when I call its constructor in the MainWindow initialization list. You can see that the dark grey OpenGL context fits the size of the window, and it seems to fill the window even when I expand and contract the window size.
Here's the same thing with parenting:
#include "mainwindow.h"
#include "rendersurface.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
renderSurface(this)
{
setCentralWidget(&renderSurface);
setWindowTitle("QtGL Test");
}
MainWindow::~MainWindow()
{
}
Simply passing 'this' to the RenderSurface constructor instead changes the way that my OpenGL context is initially rendered in my window. It's also worth noting that my RenderSurface will start filling my window properly once I resize the window by dragging an edge.
Why does making my RenderSurface a child of my MainWindow cause this issue? How can I avoid this buggy-looking behaviour? Also, since my GUI seems to work better without parenting, what are some pros and cons of object parenting in Qt?
Case 1 : You are effectively using QMainWindow layout, which is a specific layout implementation to the same extent as QGridLayout or QStackedLayout.
Case 2 : You are using the default Qt widget layout, which have a more loose setup of the children widgets. The only condition I know of is that children rectangles are within the parent rectangle and their default position is 0,0. The layout will not resize the children.
setCentralWidget(&renderSurface);will try to add renderSurface to the Qmainwindow layout. In case 2, rendersurface is already inside a layout, so this attempt will fail.
Also, since my GUI seems to work better without parenting
You are incorrect about the parenting part. In both case renderSurface becomes a child of the window.
QWidget* w = new Qwidget(0);
QLayout* l = new QHBoxLayout();
l->add(w);
setLayout(l);
During setLayout all widgets in the layout will have their affinity changed to the widget owning the layout. w is no more a parentless widget.
When a widget is going to be added to a layout, the best thing is to create it without a parent like you did. The correct parent is going to be set later.
It is a known issue. I like this answer as well: A widget with a parent doesn't become a window but is embedded into its parent. If you don't put it in a layout it might end up in a strange place on the parent and might have an arbitrary size (0x0 included). So if you want your widget to be a window, simply don't pass a parent at all. So the layout you put the widget in is the key for rendering in this case and QMainWindow is not a layout but can have a layout or a few on its own.
On the other hand, setCentralWidget is already taking care of releasing the embedded widget so there is no reason to provide the parent pointer for such widget. And setCentralWidget makes an unparented widget central and correctly drawable as if in layout.

Qt/C++ Not displaying QGraphicview as QWidget

My project consists of operations between geometric figures on a cartesian plane.I would include a graph that have to be updated after each operation.
Thats the source:
http://pastebin.com/s5Fu9dHJ
I've created the wrapper "disegna" (: public QWidget) because of I am sending to display everything as separate widgets (I have a widget for the virtual keyboard, another for Qlineedits, etc.) and I need an QWidget object can be used with view-> addWidget (QWidget,int,int) because I cannot pass directly a QMainWindow object.
The Program run with no errors,but no "hello world" is drawed (and no blank-space for istance QGraphicView is created).
where am I doing it wrong?
Change
QGraphicsView view(&scene);
view.show();
to
QGraphicsView * view = new QGraphicsView(&scene);
view->show();
The way you have it now, the instance of QGraphicView is allocated on the stack and gets destroyed right after the disegna constructor is executed, that's why you can't see it.
Don't forget to free the memory.

Display QImage within main window

I'm trying to display an image with Qt, I can get it to appear in a separate window, but I can't make it appear within the main window
Qt_first w;
w.show();
This shows the window I designed in Qt designer, how do I access the Qlabel(Image_Lbel) I put within the QWidget (centralWidget) of that window?
I generated a stripy image that shows correctly, just not within the correct window
QSize size = QSize(640,480);
QImage::Format format = QImage::Format_ARGB32;
QImage image = QImage::QImage(size, format);
//generate
QLabel myLabel;
myLabel.setPixmap(QPixmap::fromImage(image));
myLabel.show();
I get the feeling it could be I haven't included the files from the creator or the namespaces any suggestion much appreciated
I guess your Label is getting displayed independently. Set the parent of label to your main window. Then your Label will displayed inside your main window.
So use,
QLabel *myLabel = new QLabel(this); // sets parent of label to main window
myLabel->setPixmap(QPixmap::fromImage(image));
myLabel->show();
You can also use move function for moving your label within the main window.
If you want to set the label from outside the Qt_first class, you need to add a method to do this. For example (in qt_first.cpp, change qt_first.h accordingly):
void Qt_first::setImageLabel(const QImage& image)
{
ui->Image_Lble.setPixmap(QPixmap::fromImage(image));
}
ui in this example is the object that represents the UI that you created with Qt Designer.
I used a combination of both answers, thanks to both
Qt_first w; // the UI I made with Qt creator
QLabel *myLabel = w.getImageLabel();
myLabel->setPixmap(QPixmap::fromImage(image));
w.show();
With the following inside the Qt_first class
QLabel* Qt_first::getImageLabel(){
QLabel *myLabel = ui.Image_Label;
return myLabel;
}