PDA

View Full Version : Can not activate trayicon when dialog is open



cges30901
12th February 2019, 00:54
I am working on a program that can minimize to tray and hide the main window. I expect the mainwindow to show when I click on the tray icon. This usually works, but I find that if the program minimizes to tray when I call QFileDialog::getOpenFileName() to select file without closing the dialog, I cannot activate the trayicon. Does anyone know how to solve it? I am using Qt 5.12.1 on Manjaro Linux. Here is my example:

main.cpp:


#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}

mainwindow.h:


class MainWindow : public QMainWindow
{
Q_OBJECT
QSystemTrayIcon *trayIcon;
QMenu *trayContextMenu;
QAction *actShow;
QPushButton *button;

public:
MainWindow(QWidget *parent = 0);

protected:
void changeEvent(QEvent *);

private slots:
void click();
void trayIcon_activated(QSystemTrayIcon::ActivationReas on reason);
void actShow_Triggered();
};

#endif // MAINWINDOW_H

mainwindow.cpp:


#include "mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QPushButton *button = new QPushButton("button", this);
setCentralWidget(button);
connect(button,&QPushButton::clicked,
this,&MainWindow::click);
trayIcon=new QSystemTrayIcon;
trayIcon->setIcon(QIcon("hmtimer.png"));
trayContextMenu=new QMenu;
actShow=trayContextMenu->addAction(tr("Show"));
trayIcon->setContextMenu(trayContextMenu);
connect(actShow,&QAction::triggered,
this,&MainWindow::actShow_Triggered);
connect(trayIcon,&QSystemTrayIcon::activated,
this,&MainWindow::trayIcon_activated);
}

void MainWindow::changeEvent(QEvent *event)
{
if(event->type()==QEvent::WindowStateChange){
if(isMinimized()){
this->hide();
trayIcon->show();
}
}
else{
QMainWindow::changeEvent(event);
}
}

void MainWindow::click()
{
QFileDialog::getOpenFileName(this,QString());
}

void MainWindow::trayIcon_activated(QSystemTrayIcon::Ac tivationReason reason)
{
if(reason==3){ //reason==Trigger
this->show();
trayIcon->hide();
}
}

void MainWindow::actShow_Triggered()
{
this->show();
trayIcon->hide();
}

The example can be downloaded here (https://drive.google.com/file/d/1689FnfzZESzMhPwZzNGAfjVD6lzjFZew/view?usp=sharing)

It seems that if the program minimizes to tray when QFileDialog::getOpenFileName(this,QString()) is not closed, I cannot make the mainwindow appear by click on the tray icon or right click to show the context menu.

How to reproduce:

1. Open the program
2. Click on the button to open file dialog
3. Minimize to tray
4. Try clicking and right-clicking on the tray icon

anda_skoa
13th February 2019, 21:40
Well, the file dialog is "modal" on the parent window, keeping use events away from the parent as long as it is opened.

Maybe the tray icon is considered part of that part of the UI or the event sent by the tray integration to the main window is considered part of the types to filter.

Cheers,
_

cges30901
14th February 2019, 16:24
Thank you for your reply. So maybe I should not minimize to tray when the file dialog is shown?

anda_skoa
15th February 2019, 14:02
Right.

I think it makes sense to show the main window when the dialog is opened, otherwise the user sees a dialog but doesn't have a reference which program this belongs to.

Cheers,
_

cges30901
16th February 2019, 15:53
OK, this is the code that doesn't minimize to tray when dialog is open:

mainwindow.h:


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QPushButton>
#include <QEvent>
#include <QMenu>
#include <QAction>

class MainWindow : public QMainWindow
{
Q_OBJECT
QSystemTrayIcon *trayIcon;
QMenu *trayContextMenu;
QAction *actShow;
QPushButton *button;
bool dialog_open;

public:
MainWindow(QWidget *parent = 0);

protected:
void changeEvent(QEvent *);

private slots:
void click();
void trayIcon_activated(QSystemTrayIcon::ActivationReas on reason);
void actShow_Triggered();
};

#endif // MAINWINDOW_H


mainwindow.cpp:


#include "mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QPushButton *button = new QPushButton("button", this);
setCentralWidget(button);
connect(button,&QPushButton::clicked,
this,&MainWindow::click);
trayIcon=new QSystemTrayIcon;
trayIcon->setIcon(QIcon("hmtimer.png"));
trayContextMenu=new QMenu;
actShow=trayContextMenu->addAction(tr("Show"));
trayIcon->setContextMenu(trayContextMenu);
connect(actShow,&QAction::triggered,
this,&MainWindow::actShow_Triggered);
connect(trayIcon,&QSystemTrayIcon::activated,
this,&MainWindow::trayIcon_activated);
dialog_open=false;
}

void MainWindow::changeEvent(QEvent *event)
{
if(event->type()==QEvent::WindowStateChange
&& dialog_open==false){
if(isMinimized()){
this->hide();
trayIcon->show();
}
}
else{
QMainWindow::changeEvent(event);
}
}

void MainWindow::click()
{
dialog_open=true;
QFileDialog::getOpenFileName(this,QString());
dialog_open=false;
}

void MainWindow::trayIcon_activated(QSystemTrayIcon::Ac tivationReason reason)
{
if(reason==3){ //reason==Trigger
this->show();
trayIcon->hide();
}
}

void MainWindow::actShow_Triggered()
{
this->show();
trayIcon->hide();
}

cges30901
18th February 2019, 15:07
Just found that this problem is related to the operating system/desktop environment. I am using xfce, and when I minimize to tray, both mainwindow and dialog are hided.
On IceWM, only mainwindow is hided, and dialog is still shown.
On Gnome, seems that it doesn't have system tray.
On windows, both dialog and mainwindow are not hided, and tray icon is not shown (nothing happens at all).