Russian Qt Forum
Ноябрь 26, 2024, 02:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Приложение System Tray only  (Прочитано 9449 раз)
KsenZ
Гость
« : Апрель 14, 2013, 06:49 »

Собственно вопрос. Как написать приложение состоящее только из трея? Т.е. не будет не каких окон, только уведомления, и небольшое меню.
Я пробовал написать, трей работает, но выходит и совершенно пустое окно, хотя в проекте нет файла ui.
Собственно вот код:
tray.cpp
Код:
#include "tray.h"

Tray::Tray(QWidget *parent) :
    QWidget(parent)
{
    createActions();
    createTrayIcon();
    setIcon();

    trayIcon->show();
}

void Tray::createActions()
{
    open = new QAction(tr("&Open"), this);
    connect(open, SIGNAL(triggered()), this, SLOT(show()));


    close = new QAction(tr("&Quit"), this);
    connect(close, SIGNAL(triggered()), qApp, SLOT(quit()));
}

void Tray::createTrayIcon()
{
    trayIconMenu = new QMenu(this);


    trayIconMenu->addAction(open);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(close);


    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayIconMenu);


    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason)));
}

void Tray::setIcon()
{
    trayIcon->setIcon(QIcon(":/tray.ico"));
}

void Tray::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
{
    if(reason == QSystemTrayIcon::Trigger)
        this->show();
}

void Tray::closeEvent(QCloseEvent *event)
{
    if (trayIcon->isVisible()) {
        trayIcon->showMessage(tr("Still here!!!"),
                              tr("This application is still running. To quit please click this icon and select Quit"));
        hide();


        event->ignore();
    }
}

Tray::~Tray()
{
    delete trayIcon;
    delete trayIconMenu;
    delete open;
    delete close;
}
tray.h
Код:
#ifndef TRAY_H
#define TRAY_H

#include <QtGui>
#include <QWidget>
#include <QSystemTrayIcon>
#include <QCloseEvent>


class QMenu;

class Tray : public QWidget
{
    Q_OBJECT

public:
    explicit Tray(QWidget *parent = 0);
    ~Tray();

private:
    void createActions();
    void createTrayIcon();
    void setIcon();
    void closeEvent(QCloseEvent *);

    QSystemTrayIcon *trayIcon;
    QMenu *trayIconMenu;

    QAction *open;
    QAction *close;

private slots:
    void trayIconClicked(QSystemTrayIcon::ActivationReason);
};

#endif // TRAY_H
main.cpp
Код:
#include "tray.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    if (!QSystemTrayIcon::isSystemTrayAvailable())
    {
        QMessageBox::critical(0, QObject::tr("Tray"),
                              QObject::tr("I couldn't detect any system tray "
                                          "on this system."));
        return 1;
    }

    QApplication::setQuitOnLastWindowClosed(false);

    Tray w;
    w.show();
   
    return a.exec();
}
Записан
Serr500
Гость
« Ответ #1 : Апрель 14, 2013, 08:57 »

То, что ui нет, здесь не имеет значения - у Вас есть потомок QWidget, который и будет главным окном. Убирайте QWidget, оставляя только QTrayIcon. Если надо ловить сигналы, создайте класс-потомок QObject.
Записан
KsenZ
Гость
« Ответ #2 : Апрель 14, 2013, 11:42 »

То, что ui нет, здесь не имеет значения - у Вас есть потомок QWidget, который и будет главным окном. Убирайте QWidget, оставляя только QTrayIcon. Если надо ловить сигналы, создайте класс-потомок QObject.
Не совсем понял...
Если класс будет наследоваться от QObject, то у него не будет метода show(), как тогда трей "отобразить"? Т.е. в main.cpp:
Код:
Tray w;
w.show();

Не будет отрабатывать.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #3 : Апрель 14, 2013, 12:35 »

я бы сделал так:
Код:
#include "mainwindow.h"
#include <QApplication>

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

    if(onlyTray)
        w.showTray();
    else
        w.show();
   
    return a.exec();
}
Код:
#include "ui_mainwindow.h"

class QSystemTrayIcon;
class QAction;
class QMenu;

class MainWindow : public QMainWindow, private Ui::MainWindow
{
    Q_OBJECT

private:
    QSystemTrayIcon *trayIcon;
    QAction *quitAction;
    QMenu *trayIconMenu;
public:
    explicit MainWindow(QWidget *parent = 0);

    void showTray();
};

const bool onlyTray=true;
Код:
#include "mainwindow.h"
#include <QSystemTrayIcon>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    setupUi(this);
}

void MainWindow::showTray(){
    // создание иконки
    trayIconMenu = new QMenu(this);
    quitAction = new QAction(tr("Выход"), this);
    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
    trayIconMenu->addAction(quitAction);

    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayIconMenu);
    trayIcon->setIcon(QIcon(":/blueflag.png"));
    trayIcon->setToolTip(this->windowTitle());
    trayIcon->show();
}
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
VPS
Гость
« Ответ #4 : Апрель 14, 2013, 12:39 »

А что мешает отнаследоваться только от "QSystemTrayIcon"?
Записан
KsenZ
Гость
« Ответ #5 : Апрель 14, 2013, 12:50 »

А что мешает отнаследоваться только от "QSystemTrayIcon"?
А сигналы как ловить без QObject?
Записан
VPS
Гость
« Ответ #6 : Апрель 14, 2013, 13:00 »

А сигналы как ловить без QObject?

QSystemTrayIcon Class Reference

The QSystemTrayIcon class provides an icon for an application in the system tray. More...
 #include <QSystemTrayIcon>

Inherits: QObject.
« Последнее редактирование: Апрель 14, 2013, 13:02 от vps » Записан
Serr500
Гость
« Ответ #7 : Апрель 14, 2013, 13:31 »

Вот Вам простенький примерчик.
Записан
KsenZ
Гость
« Ответ #8 : Апрель 14, 2013, 14:14 »

Спасибо всем за ответы. Попробую завтра разобраться.
Записан
KsenZ
Гость
« Ответ #9 : Апрель 15, 2013, 04:07 »

Попробовал, спасибо все работает.
Вот только есть один вопрос, он конечно к теме не относится, но все же.

Если в хидере я объявляю
Код:
QSystemTrayIcon *tray;
QMenu *trayMenu;

приложение собирается, но при запуске segmentation fault

а если
Код:
QSystemTrayIcon tray;
QMenu trayMenu;

то все нормально.
Записан
Serr500
Гость
« Ответ #10 : Апрель 15, 2013, 08:28 »

А new и delete для них вызываете? Сдаётся мне, что нет. Подмигивающий
Записан
Bepec
Гость
« Ответ #11 : Апрель 15, 2013, 12:03 »

КсенZ, надо учить плюсы (С++).

int *b - это создание указателя на объект. Пока ты объект не создашь, то указатель при обращении будет посылать всех в жо лес.

Почитай про указатели и ссылки.
Записан
Serr500
Гость
« Ответ #12 : Апрель 15, 2013, 13:51 »

Пока ты объект не создашь, то указатель при обращении будет посылать всех в жо лес.
Не обязательно. Можно случайно при инициализации получить валидный адрес и считать хрен знает что. Это гораздо хуже SEGFAULT - не валится, но результат работы непредсказуемый. Поэтому я всегда в конструкторах пихаю в указатели NULL - это лучше чем ошибка, проявившаяся через миллион строк совершенно в другом месте.

P.S. Вероятно, человек либо новичок в программировании, либо раньше писал на языках, где конструкции типа T* t автоматически создают объекты.
Записан
Bepec
Гость
« Ответ #13 : Апрель 15, 2013, 14:15 »

Есть ещё вариант. Что он писал на языках без указателей Улыбающийся
Записан
KsenZ
Гость
« Ответ #14 : Апрель 16, 2013, 03:37 »

Я знаю, что int *b - это создание указателя на объект.
Вопрос у меня вот какой. Как лучше делать?
Код:
QMenu trayMenu;
trayMenu.addSeparator();
или же
Код:
QMenu *trayMenu;
trayMenu = new Qmenu;
trayMenu->addSeparator();
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.066 секунд. Запросов: 23.