Minimizing Application to Tray
-
I am using Microsoft Windows 7 Ultimate.
This is mainwindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QWidget>
#include <QSystemTrayIcon>#include <QMainWindow>
class QMenu;
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
bool createConnection();private:
Ui::MainWindow *ui;// Tray Icon Functions void createTrayActions(); void createTrayIcon(); void setTrayIcon(); void closeEvent(QCloseEvent *); void changeEvent(QEvent *); QSystemTrayIcon *trayIcon; QMenu *trayIconMenu; QAction *showHideTray; QAction *closeTray;
private slots:
void trayIconClicked(QSystemTrayIcon::ActivationReason);
void showHideWindow();};
#endif // MAINWINDOW_H@
This is mainwindow.cpp
@#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QtSql/QSqlError>
#include <QMenu>
#include <QCloseEvent>
#include <QDir>MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);createTrayActions(); createTrayIcon(); setTrayIcon(); trayIcon->show();
}
void MainWindow::changeEvent(QEvent *event)
{
QMainWindow::changeEvent(event);
if(event->type() == QEvent::WindowStateChange) {
if(isMinimized())
this->hide();
}
}void MainWindow::closeEvent(QCloseEvent *event)
{
if (trayIcon->isVisible()) {
showHideWindow();
event->ignore();
}
}void MainWindow::showHideWindow()
{
if(this->isVisible())
{
this->hide();
showHideTray->setIcon(QIcon(":/images/arrow_up.ico"));
showHideTray->setText("Show Main Window");
}
else
{
this->show();
showHideTray->setIcon(QIcon(":/images/arrow_down.ico"));
showHideTray->setText("Hide Main Window");
}
}void MainWindow::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::DoubleClick)
showHideWindow();
}void MainWindow::setTrayIcon()
{
trayIcon->setIcon(QIcon(":/images/Download.ico"));
}
void MainWindow::createTrayIcon()
{
trayIconMenu = new QMenu(this);
trayIconMenu->addAction(showHideTray);
trayIconMenu->addSeparator();
trayIconMenu->addAction(closeTray);trayIcon = new QSystemTrayIcon(this); trayIcon->setContextMenu(trayIconMenu); connect( trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason)) );
}
void MainWindow::createTrayActions()
{
showHideTray = new QAction(tr("&Hide Main Window"), this);
connect(showHideTray, SIGNAL(triggered()), this, SLOT(showHideWindow()));
showHideTray->setIcon(QIcon(":/images/arrow_down.ico"));
closeTray = new QAction(tr("&Exit"), this);
connect(closeTray, SIGNAL(triggered()), qApp, SLOT(quit()));
closeTray->setIcon(QIcon(":/images/Delete.png"));
}
MainWindow::~MainWindow()
{
delete ui;
delete trayIcon;
delete trayIconMenu;
delete showHideTray;
delete closeTray;
}@ -
If it can be useful for those is trying to solve this problem:
Actually I develop under linux ubuntu then rebuild under windows 7 ultimate and under xp. I use virtual machines but it doesn't matter, the machine is as a real computer (little slow).
Using the beta Qt-Quick and Qt-Creator + Qt-sdk (all Qt wrote correct, eh Andre ? :) :) ) I experience problems under Windows 7. Strange problems that probably are not so depending from the application itself.
-
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.