Minimizing Application to Tray
-
Hi khalidmushta..,
I created an app using sys tray icon which works on windows 7.
You can find the sources on "gitorious":http://gitorious.org/giesbert-s-software/giesbert-s-world-clockThe code, where I minimize / restore to / from system tray looks like this:
@
void GiWorldClock::hideEvent(QHideEvent* pEvent)
{
if(isMinimized())
{
::ShowWindow(this->winId(), SW_HIDE);
m_pRestoreAction->setEnabled(true);
m_pMinAction->setDisabled(true);
}
QWidget::hideEvent(pEvent);
}void GiWorldClock::showEvent(QShowEvent* pEvent)
{
QWidget::showEvent(pEvent);
::ShowWindow(this->winId(), SW_SHOW);
m_pRestoreAction->setDisabled(true);
m_pMinAction->setEnabled(true);
}
@ -
I started the debugger on and when I minimize application it displays following error..
(Internal error: pc 0x111 in read in psymtab, but not in symtab.)
When I close application, it shows no error and hides the application to tray..
-
Just a small advice, what I will do in your case. Why don't remove from the windows the minimize button, leaving only the close, that works fine? Two buttons that do the same thing can confuse the user, not ?
-
ya.. nice advice:-)
-
I had the same problem with a windowless device... Decided for this solution :)
-
To remove the button is no solution...
Here is a dirty hack, but it works.@void MainWindow::changeEvent(QEvent *e)
{
if(isMinimized())
{
show(); // The hack
slotToggleVisibility(); // Your tray icon code
}
}@ -
If anyone still has this issue, the solution is to call qApp->processEvents() before calling hide(), ie.
@void ApplicationWindow::changeEvent(QEvent *event)
{
QWidget::changeEvent(event);
if (event->type() == QEvent::WindowStateChange)
{
QWindowStateChangeEvent e = (QWindowStateChangeEvent)event;
// make sure we only do this for minimize events
if ((e->oldState() != Qt::WindowMinimized) && isMinimized())
{
qApp->processEvents();
hide();
event->ignore();
}
}
}
@The test for the old state is probably unnecessary, but can't hurt.
If this doesn't help in your particular situation, try calling hide from a single-shot timer, so that the call is outside the minimize event handler:
@void ApplicationWindow::changeEvent(QEvent *event)
{
QWidget::changeEvent(event);
if (event->type() == QEvent::WindowStateChange)
{
QWindowStateChangeEvent e = (QWindowStateChangeEvent)event;
// make sure we only do this for minimize events
if ((e->oldState() != Qt::WindowMinimized) && isMinimized())
{
QTimer::singleShot(0, this, SLOT(hide()));
event->ignore();
}
}
}
@ -
Hi Ryan,
take care if you call qApp->processEvents(), as you reopen the event queue and it might happen that an event, that should be worked on after you finished is processed now. I don't say never do it, but do it with care and always remember, synchronous workflow is broken up here.
Even a deleteLater might be processed so an object can be deleted, where you expect it not to be deleted.