What did QWidget* QApplication::mainWidget() become in Qt4? - c++

I am porting an application from Qt3 to Qt4, and need a Qt4 replacement for QApplication::mainWidget() which used to return the top-level widget in Qt3. Does anyone know how to do this in Qt4?

Technically, any widget initialized with NULL is a top level widget so QApplication shouldn't assume that one of them is better than another.
The way I usually do it is to save a pointer to the "real" main widget somewhere, even a global variable or a singleton and reference it when needed.

I think topLevelWidgets() is as close at it can be.
Edit:
Yup. Qt4 added complexity (and power). There is no application wide MainWidget anymore. Many QMainWindows can be created and shown, and hidden, and shown again. This is a good thing, though :)
As shoosh noticed, QT3 behaviour can be easily simulated with global variable (yuck!) or QApplication subclass.

I think what you're looking for has been replaced by the QMainWindow class, which does allow you to set a set and get a central widget.

Related

Changing application's main window GUI layout to be in code

In my application the main window's GUI is designed in the Qt-Creator designer. I have had some trouble in getting it to look just the way I'd like, but I can when doing the GUI in C++ code.
So, I plan to change the application's main window to be laid out in code.
What should I keep in mind when doing this?
How do I make sure all the menu items and button clicks etc. get migrated, too?
In my Qt experience I almost always write layout in code and here is what I can suggest:
a) Spend some time thinking which Layout to use, personally I tend to use either QGridLayout or nested QHboxLayout and QVBoxLayout which give you lot of flexibility.
b) I normally declare all child widgets as class variables always pointers and I create the real objects in the Main windows constructor.
About not to forget any control I suggest to print the XML of the UI file and draw a line on each control you recreate in the code.
As a good starting point, simply copy-pase the setupUi method from the ui_xxx.h file that uic had generated for you. You can then manually edit the setup code to suit your needs.

How can I create a very dumb QWidget?

I need a "dumb" QWidget which doesn't do anything, only provides a HWND and can be added as a child to other QWidgets. Specifically, it should not try to manage the mouse cursor (that is my problem with simply instantiating a QWidget). (motivation: I have an in-place activated ActiveX Control, which tries to change the mouse cursor sometimes, but the QWidget changes it back to the default, so it is flickering)
The code that does the cursor changing is not within QWidget, so no QWidget changes would fix the problem. It's QApplication that does it, from within the internal QApplication::dispatchEnterLeave(...). Eventually, it is qt_win_set_cursor that does the job.
I don't readily see how it'd be possible to change this behavior without changing Qt sources.
I would suggest reporting is as a Qt bug. Qt should be checking if the native cursor was changed upon leaving alien widgets, and if such, would need to preserve it. You'd have better chances of the bug getting fixed quickly if you'd provide a patch to actually fix the issue.
Workaround: To prevent flicker, set an application-wide cursor override using QApplication::setCursorOverride(). This fixes the flicker but won't fix the control being unable to change the cursor.

Qt QMainWindow central widget deletion

my application requires the user to switch between several screens. The way I'm doing this is by creating different QFrames for each screen, and then setting the Qframes as central widgets on the MainWindow. The problem is that every time I call setCentralWidget(frame), the old frame gets deleted and I can't access it later. How can save that old frame so that I can access it later?
Please let me know if I am unclear in my question.
You can remove your central widget from QMainWidow reparenting it. Then, you could set new centralWidget;
QWidget* savedWidget = mainWnd->centralWidget();
savedWidget->setParent(0);//now it is saved
mainWnd->setCentralWidget(newWidget);
Also using QStackedWidget possibly would be better solution.
QStackedWidget is an elegant solution for this problem, you can find out how to use it properly here.
You can play around with .hide()/.show() on the appropriate subwidgets to accomplish this. But a better solution for your case is almost certainly to use a QTabWidget or QStackedWidget.

Qt -how to know whether content in child widgets has been changed?

In QMainWindow I have 2 QSplitters. In that splitters I have QTextEdit, QLineEdits, QTableWinget, Ragio buttons and so on... I want to know if somthing has been chaged after pressing File->New menu button. Is there any general method for doing this?
Somwhere I have read that it is recomended to use isWindowModified() function of QMainWindow, but seems it doesn't work.
setWindowModified() does not propagate the windowModified flag to the parents. This bug is described here: https://bugreports.qt.io/browse/QTBUG-20150. I have just tried it and indeed it did not work.
The isWindowModified() could be useful here since according to http://doc.trolltech.com/4.6/qwidget.html#windowModified-prop it propagates up to the parent.
However, I think you would need to set this yourself. For example, if you clicked the new button which leads to some text being inserted into a QTextEdit, you still need to call QTextEdit's setWindowModified() function - which will then propagate up to your QMainWindow - and you can just check QMainWindow afterwards. (However, you wouldn't know which children were modified)
Maybe you should have a look at QWidget::changeEvent.

Is there a way to determine if a top level Qt window has been moved?

I am trying to determine when the main window of my application has been moved. The main window is a standard QMainWindow and we've installed an eventFilter on the QApplication to look for moveEvents for the QMainWindow, but none are being triggered. For a variety of reasons, subclassing the QMainWindow isn't really an option.
Any thoughts on this, aside from starting a QTimer tto constantly check the position, would greatly be appreciated.
I guess it's better to install the event filter at the top-level window, instead of the application. However, if you still do not get QMoveEvents and you're working on Windows, you probably can override winEventFilter() and wait for WM_MOVE. Similar functionality might be available for Linux and Mac.
I usually do not recommend to break the platform-independence, but sometimes it might make sense.
Subclassing is really the best solution :-/
In the class that implements your top level windows you just overload this function:
virtual void moveEvent ( QMoveEvent * event )
From the documentation:
This event handler can be
reimplemented in a subclass to receive
widget move events which are passed in
the event parameter. When the widget
receives this event, it is already at
the new position.
The old position is accessible through
QMoveEvent::oldPos().
This should allow you to detect if your main window has moved. Why can't you subclass? Are you using an instance of QMainWindow directly? The usual use case is to subclass it anyway.