Why won't my qt centralWidget (a QGLWidget) resize properly? - c++

I have an application with a QMainWindow that should ideally have a QGLWidget centered on it, with spaces left around the outside for toolbars and other top/side widgets.
Unfortunately, no matter what size or geometry the QGLWidget is set to, it appears enormous and takes up the entire main window!
Basically, the setup is as follows: CreateWindow() is called in main(), which constructs the main window and calls a function Init(), which constructs the GLWidget. So, within Init(), which is a member of my adapted main window class, I essentially have:
GLScene = new MyQGLWidget(this);
setCentralWidget(GLScene);
Now, to make the GLScene conform to its desired size and position, I first tried setting its geometry within the GLWidget (a.k.a. my class derived directly from GLWidget) constructor:
MyQGLWidget::MyQGLWidget(QWidget* parent){
....
setGeometry(210, 40, 600, 400); //the main window is of course bigger and should fit this nicely
....
}
This, however, didn't work at all and still made it take up the entire main window. Instead, I tried putting the setGeometry call into Init(). I tried it both right before and right after setCentralWidget(); neither option worked. Nor did flat-out removing the setCentralWidget call (in fact, this made the GLWidget disappear).
Since this clearly isn't working properly, what is the correct way to scale the GLWidget? Or is it just a matter of how things are ordered that I need to look into more deeply?

You need to add a layout to it. I have exactly the same thing ( a widget derived from QGLWidget) whose parent calls the resize function. This solved all my issues and made it to where I can change its size at runtime.

Related

Using QRubberBand outside of my program

I'm using QRubberband and it's working fine inside of my program, but I want to get the coordinates outside of my program. In other words, using it outside of my program while it's running!
To be more clear, I'm using a Qt class called QRubberband which helps you select a rectangle or line "clicking and then drag." Everything is working when I use it inside of my project space, but I can't use it outside - for example when I activate it I should be able to select from maybe this site, or anywhere in the screen not just my program.
The QRubberBand man page says:
If you pass a parent to QRubberBand's constructor, the rubber band
will display only inside its parent, but stays on top of other child
widgets. If no parent is passed, QRubberBand will act as a top-level
widget.
So at the risk of asking the obvious... are you passing in NULL as the second argument to the QRubberBand constructor?

QWidget Transformation

I am writing an application using Qt and would like to have a "Metro Style" interface. Everything is finished except I don't know how to make the widget appear and disappear. For instance, in WPF you can animate (UIElement.RenderTransform).(TranslateTransform.Y) so that Y becomes zero or negative. How can I move the QWidget in a QGridLayout so that it can hide?
Example:
After doing some research I figured out a way to do this. Instead of letting Qt do the layout I simply handled it myself via move and set width/height functions. Overriding resizeEvent made it so I could update the values in case the window was resized. Additionally I used setMask to ensure that the widget did not leak over to unwanted locations in the UI.

QGLWidget not receiving calls to resizeGL after initialization

I am having what appears to be the same problem as asked in this (unanswered) question: Qt resizeGL problem
I am testing a new QGLWidget for a larger application. The resizeGL method is wired up to change the glViewport and repaint the OpenGL view. My QGLWidget is not part of a layout and is simply being created displayed as follows:
boost::shared_ptr<StandardCustomWidgetBuilder>
builder(new StandardCustomWidgetBuilder());
WaterfallDirector<StandardCustomWidgetBuilder, DataSource> director(builder);
director.construct();
std::unique_ptr<CustomWidget> widget = builder->getWidget();
widget->show();
On my computer, this defaults to creating a 640x480 window and calls resizeGL upon initialization. Whenever I resize the window, resizeGL is never called.
In my attempts to remedy this I have attempted creating a separate QWidget that has a QVBoxLayout containing only the CustomWidget. This created a very small window, so I fixed my sizeHint and sizePolicy for CustomWidget, though this still had no affect on having resizeGL called. At this point I'm not sure precisely how to proceed.
I resolved my problem with some help from my co-worker. As it turns out, I had implemented the event method and forgot to call the QGLWidget::event method inside it. The widget now correctly resizes.
If you haven't done so already, I would suggest checking the size hints and size policies of all widgets concerned.
For example, the following will make sure your widget uses available space when the window grows:
widget->setSizePolcy( QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding );
I don't think that the default size policy for QGLWidget makes it want to expand, so I'm thinking it's just possible that this needs changing.

How to get mouse pressed events in the root widget of a hierarchy in Qt

I have the following problem with Qt (no answer on this site seemed to address exactly this problem so I create my own question).
I have an application with a MainWindow class which inherits from QWidget. At a certain point there is a table inside the main window and I want to catch all mouse pressed events outside that table.
My first solution was to reimplement the method
/* virtual */ void MainWindow::mousePressEvent(QMouseEvent *event)
In this method, I check the position of the event and check that it is not within the QRect of the table. Unfortunately, I realized that mousePressEvent() is not always called. I suspect that if I click on another child widget of MainWindow, that widget consumes the event and does not pass it through to the parent.
So the only alternative idea I had was to reimplement the mousePressEvent() method for all the widgets contained in MainWindow. This is of course not feasible, because:
There a lot of them: it would be very complex, time-consuming, error-prone, and difficult to maintain if one had to change all the widget classes that are instantiated inside MainWindow.
Some of the subwidgets are implemented in some library modules developed in a parallel project, so I cannot change those.
In other cases, the subwidgets use Qt classes directly.
Even if I defined custom subclasses for 2 and 3, I would have to make sure that these subclasses are used everywhere instead of the original classes. This might imply again falling back to case 2.
So this alternative solution seems unfeasible to me.
Summarizing: Do you know if there is a simple method to catch all mouse clicks on the main window from within the MainWindow class?
You could do this by installing an event filter in the main window. Take a look at QObject::installEventFilter() in the Qt docs.
You can set the attribute Qt::WA_TransparentForMouseEvents with QWidget::setAttribute to all the child widgets except the table to get the mouse events in the MainWindow (which will only work if the table is a direct child of MainWindow).
Or do the opposite, and add a transparent widget above your whole MainWindow with a hole at the position of the table. And you set/unset the Qt::WA_TransparentForMouseEvents to that widget when you want it to let the clicks pass or to catch them.
The hole can be created with QWidget::setMask() and QRegion::substracted().

How do I make Qt graphs appear in the same window?

I am working in Qt in my program. I have a widget window and I have placed a button and a list box in it. Then I have made a class called myplot which graph plotting is done. Then in my button event handler I have called the object of myplot
myplot * p1 = new myplot(session,session ,24, "session"); // send arrays in argument containing the data to be plot
p1->show();
myplot * p2 = new myplot(payload,payload ,24, "payload"); // send arrays in argument containing the data to be plot
p2->show();
It is working fine as my graph appear in new window, but what I want is that graphs should appear in my mainwidget window.
What I did next was to remove the title bar of my graphs window I wrote this
Qt Code:
p1->setWindowFlags(Qt::FramelessWindowHint);
p2->setWindowFlags(Qt::FramelessWindowHint);
Now
1) what should I do to place and append the graphs window in my main window? Also when I close main window my graph window should close.
2) when I select an other value from the list box and click button my old graph disappear and new should appear
i drag and droped a verticlalayout then write
ui->verticalLayout->addChildWidget(p1);
but got an error
/usr/include/qt4/QtGui/qlayout.h:191: error: ‘void QLayout::addChildWidget(QWidget*)’ is protected
then i draaged and droped a scrollarea and wrote
myplot * p1 = new myplot(session,session ,24, "session");
p1->setWindowFlags(Qt::FramelessWindowHint);
ui->scrollArea->addScrollBarWidget(p1,0);
p1->show();
my graphs stopped appearing kindly guide me am i doing it wrong or what the right way
Apparently, myplot is a childclass of QWidget. So you can just define a layout on your main window (e.g. using QHBoxLayout), and add those two widgets to it. This will cause them to be drawn inside the mainwindow. Also make sure that you pass the main window as the QWidget parent of the plots.
For replacing the plots, you can either remove the old plots from the layout and add new ones. But I would prefer to make the plots members of your main window and include some update method that would redraw with the new data
When you call show on widgets with no parent like that, it automatically gets wrapped in a window. What you should do is create one widget and add the graphs to it's layout. See QMainWindow examples, and section about dock widgets if that's what you want.
Basically you don't need to worry about the window they are appearing in, it is only appearing because they have no other parent.
What you need to do is to specify a parent widget when you construct them.
(This answer is based on the assumption that your plots are also QWidgets, if you could mention what class they actually are and perhaps link to the documentation it would really help us to answer you.)