I have a QSplitter and two child widgets in it. Let's say p_widget_1 and p_widget_2. p_widget_1 is allowed to be closed, it has a Close button and when Close is clicked I call p_widget_1->hide(). QSplitter doc says:
When you hide() a child, its space will be distributed among the other children. It will be reinstated when you show() it again.
But I want the QSplitter's handle to keep its position as I have a requirement that p_widget_2 should have fixed size.
How do I achieve it? My current approach is calling p_splitter->setSizes() when necessary but it doesn't always work in all my cases.
I am on Windows, QT is 5.4.1, Visual Studio 2013.
I didn't try on a particular QWidget (like your QSplitter) but this is what I do when I want to restore the geometry of a window after it is closed:
Before the child is hidden, save the QByteArray retrieved with the
following function (on your QSplitter)
QByteArray QWidget::saveGeometry() const
After the child is displayed again, call the following method with
the QByteArray you just stored
bool QWidget::restoreGeometry(const QByteArray & geometry)
Documentation here.
I am not sure this solve your problem or not. Try 'saveSate' method to save state of QSplitter and restore it by 'restoreState' method.
Related
I would like to know if the following is possible as I have been searching but haven't found anything that answers my question. The closest i've got it QTextCursor typing on the a QTextDocument. (Not what I want).
What I am looking for is a method of typing data wherever the textcursor is on screen, (even if its not in the qt app window), once a qpushbutton has triggered a 'clicked' event. I have set the push button up and push button event up. I just havent found a way to get the data to type to the screen.
Any help would be appreciated.
It depend on the platform, and it's not related to Qt, for example with windows you could see the answer of Xavier Poinas at this link Insert text into the textbox of another application
And if you just want floating text, you could use QLabel without parent, place your QLabel with setGeometry or move at the point given by QCursor::pos() or QCursor::pos(const QScreen *).
I have a question regarding dragging QDockWidgets between QMainWindows. I have an application with different "DockAreas" which have a QMainWindow member with one or more QDockWidgets. Additionally, I want to make QDockWidgets drag-and-droppable into other, already floating QDockWidgets (not tabbed!).
To have the nice hover-effect upon drag-and-drop, the floating QDockWidgets are embedded in a new instance of my DockArea with the QMainWindow member. Now I intercept the mousemove event of the dragged QDockWidget and change its parent when it hovers over another QMainWindow of my DockArea. Unfortunately, this causes a crash and it looks like the original QLayoutItem, where this QDockWidget was in, is gone.
void QDockWidgetPrivate::moveEvent(QMoveEvent *event)
{
// ...
// now this widgetItem member of state is kaputt
layout->hover(state->widgetItem, globalMousePos);
}
I found different suggestions for dragging-dropping QDockWidgets between QMainWindows on the internet:
1) Re-parenting - that's what I am trying atm
2) QDrag - did not work for me, async exec() breaks my application and at the end I have to reparent anyway
3) Call addDockWidget(...) of the new QMainWindow - docks the QDockWidget and I would have to make it floating again and somehow "continue the dragging"
I am open to any new suggestions :) Thank you in advance!
I'm wrestling with the same Problem right now and want to share.
Ich found this forum post dealing with the same problem: http://www.qtcentre.org/threads/41847-Dragging-QDockWidgets-between-QMainWindows
This solution is however flawed: it doesn't work properly if you allow the Dockables to be floating. And the enterEvent does not actually trigger when you enter the other window and still dragging the QDockWidget. It only triggers after release.
I'm also going for the reparenting (1). QDrag seems problematic when you also want to allow rearranging the QDockWidget within the Window.
I think one would correctly do this by reacting to the drop/release of the dragged QDockWidget. But I can't find an event or signal for this.
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.
I'm using Qt 4.7 on Windows 7 Ultimate 32 bit.
The QMainWindow of my program has a QDockWidget. I've noticed that if I minimize the main window by the minimize button on the title bar, after restoring it the dock widget is closed. I didn't write any support for a feature like this!
How does this happen and how to prevent this?
Thanks.
I encountered this error when writing my own application. I have QDockWidget with options for my application. Using Qt Creator I created menu with QAction actionMenu which was checkable. Then I connected QDockWidget and QAction like this:
QObject::connect(ui->dockWidget, SIGNAL(visibilityChanged(bool)),
ui->actionMenu, SLOT(setChecked(bool)));
QObject::connect(ui->actionMenu, SIGNAL(toggled(bool)),
ui->dockWidget, SLOT(setVisible(bool)));
The order of connection is not important. And then when I minimized application with QDockWidget being visible, after I restored it QDockWidget was closed and actionMenu was unchecked.
In fact there are two solutions. First which works for me is to use SIGNAL(triggered(bool)) instead of SIGNAL(toggled(bool)):
QObject::connect(ui->dockWidget, SIGNAL(visibilityChanged(bool)),
ui->actionMenu, SLOT(setChecked(bool)));
QObject::connect(ui->actionMenu, SIGNAL(triggered(bool)),
ui->dockWidget, SLOT(setVisible(bool)));
The second solution uses action which you can obtain from QDockWidget:
// Retrieve action from QDockWidget.
QAction *action = ui->dockWidget->toggleViewAction();
// Adjust any parameter you want.
action->setText(QString("&Menu"));
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
action->setStatusTip(QString("Press to show/hide menu widget."));
action->setChecked(true);
// Install action in the menu.
ui->menuOptions->addAction(action);
I know for sure that SIGNAL(toggled(bool)) was causing in my application closure of QDockWidget.
I faced the same problem... I managed to get rid of it by using a method called StoreWindowsLayout and RestoreWindowsLayout.
StoreWindowsLayout will save the content of the ByteArray returned by the Method QMainwindow::saveState().
RestoreWindowsLayout will restore that bytearray, and therefore your windows layout, the qdockwidget visibility state and so on...
I call StoreWindowsLayout on ApplicationMainFrm::changeEvent, on ApplicationMainFrm::closeEvent (it's likely this one you'll need) and in ApplicationMainFrm::hide().
Then I use restoreWindowsLayout in ApplicationMainFrm::showEvent.
Exemple of use of restoreWindowsLayout in my MainForm :
void ApplicationMainFrm::showEvent(QShowEvent* pEvent)
{
QMainWindow::showEvent(pEvent);
restoreWindowsLayout();
}
Hope it helps !
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.