Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: virtual_root от Декабрь 17, 2010, 21:59



Название: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 17, 2010, 21:59
Доброго времени суток! Подскажите,пожалуйста,решение!
 Я использую класс QSystemTrayIcon, программа после запуска приложения появляется в области оповещения,но с панели задач не могу заставить её уйти! А если свернуть приложение она остаются только в области оповещения, а мне нужно было чтобы она сразу там была при запуске. Может кто-нибудь сталкивался с подобным?

Пишу такой код: файл .h
Код:
class SystemTray : public QLabel {
Q_OBJECT
private:
    QSystemTrayIcon* m_ptrayIcon;
    QMenu*           m_ptrayIconMenu;
    bool             m_bIconSwitcher;

protected:
    virtual void closeEvent(QCloseEvent*);

public:
    SystemTray(QWidget* pwgt = 0);


};

Файл .cpp :
Код:
SystemTray::SystemTray(QWidget* pwgt)
    : QLabel("", pwgt)
    , m_bIconSwitcher(true)
{

    QAction* pactQuit = new QAction("&Quit", this);
    connect(pactQuit, SIGNAL(triggered()), qApp, SLOT(quit()));
    m_ptrayIconMenu = new QMenu(this);
    m_ptrayIconMenu->addAction(pactQuit);

    m_ptrayIcon = new QSystemTrayIcon(this);
    m_ptrayIcon->setContextMenu(m_ptrayIconMenu);
    m_ptrayIcon->setToolTip(QString::fromLocal8Bit("Ёлочка"));
    m_ptrayIcon->setIcon(QPixmap(":/images/icon.gif"));
    m_ptrayIcon->show();
}

void SystemTray::closeEvent(QCloseEvent* pe)
{
    if (m_ptrayIcon->isVisible()) {
        hide();
    }
}

В файле main.cpp только создаю объект своего класса.


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: SimpleSunny от Декабрь 17, 2010, 22:46
В конце конструктора допишите hide() или QTimer::singleshot(0, this, hide());


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 17, 2010, 23:28
дописала hide(), но это не помогло.
В своей программе я создаю gif анимацию,новогоднюю елочку,хотела чтобы она запускалась,пряталась в область оповещения,но сама ёлочка всегда оставалась на рабочем столе. Всё сделала,а вот убрать с панели задач не могу...
Файлы программы: systemtray.h
Код:
#ifndef SYSTEMTRAY_H
#define SYSTEMTRAY_H

#include <QLabel>

class QSystemTrayIcon;
class QMenu;
class SystemTray : public QLabel {
Q_OBJECT
private:
    QSystemTrayIcon* m_ptrayIcon;
    QMenu*           m_ptrayIconMenu;
    bool             m_bIconSwitcher;

protected:
    virtual void closeEvent(QCloseEvent*);

public:
    SystemTray(QWidget* pwgt = 0);


};

#endif // SYSTEMTRAY_H

systemtray.cpp
Код:
#include "systemtray.h"
#include <QtGui>
#include <QTimer>

SystemTray::SystemTray(QWidget* pwgt /*=0*/)
    : QLabel("", pwgt)
    , m_bIconSwitcher(true)
{

    QAction* pactQuit = new QAction("&Quit", this);
    connect(pactQuit, SIGNAL(triggered()), qApp, SLOT(quit()));
    m_ptrayIconMenu = new QMenu(this);
    m_ptrayIconMenu->addAction(pactQuit);

    m_ptrayIcon = new QSystemTrayIcon(this);
    m_ptrayIcon->setContextMenu(m_ptrayIconMenu);
    m_ptrayIcon->setToolTip(QString::fromLocal8Bit("Ёлочка"));
    m_ptrayIcon->setIcon(QPixmap(":/images/icon.gif"));
    m_ptrayIcon->show();
    hide();
}

void SystemTray::closeEvent(QCloseEvent* pe)
{
    if (m_ptrayIcon->isVisible()) {
        hide();
    }
}

main.cpp
Код:
#include "systemtray.h"
#include <QtGui>
class Window : public QLabel {
private:
    QPoint  m_ptPosition;

protected:
    virtual void Window::mousePressEvent(QMouseEvent* pe)
    {
        m_ptPosition = pe->pos();
    }

    virtual void Window::mouseMoveEvent(QMouseEvent* pe)
    {
        move(pe->globalPos() - m_ptPosition);
    }

public:
    Window(QWidget* pwgt = 0)
        : QLabel(pwgt,  Qt::FramelessWindowHint | Qt::Window)
    {
    }
};

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    SystemTray   st;
    Window       win;
    QMovie       mov("elka7.gif");
    QPixmap  pix(":/images/elka7.gif");
    win.setMask(pix.mask());
    win.setMovie(&mov);
    win.resize(240,400);
    win.show();
    mov.start();
    return app.exec();
}
и конечно же файл ресурсов с картинками.


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: SimpleSunny от Декабрь 17, 2010, 23:33
http://www.forum.crossplatform.ru/index.php?showtopic=3333
http://www.prog.org.ru/topic_9754_0.html;prev_next=next


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 18, 2010, 00:13
огромное спасибо! Помогла установка флага Qt::Tool.


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 18, 2010, 00:34
Извините,пожалуйста,за глупый вопрос. Но возможно ли собрать мою программу в один exe файл, чтобы не приходилось тащить  собой библиотеки:qtcored4.dll , mingwn10.dll , qtgui4.dll (этот файл аж 131 мегабайт!!! это же ужас с собой столько таскать!) Читала на форуме статьи http://www.prog.org.ru/topic_15839_0.html и http://www.prog.org.ru/topic_15904_0.html, но что-то смутно понимаю что нужно делать. Из консоли что ли придётся собирать exe-шник? Как это тогда правильно сделать???


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: SimpleSunny от Декабрь 18, 2010, 00:34
компилируйте в релиз сборке и носите около 10Мб


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 01:03
почему то я попробовал ваш пример и у меня ругается компилятор на эти строки

    virtual void Window::mousePressEvent(QMouseEvent* pe)
    {
        m_ptPosition = pe->pos();
    }
    virtual void Window::mouseMoveEvent(QMouseEvent* pe)
    {
        move(pe->globalPos() - m_ptPosition);
    }

вот такое выдает
extra qualification 'Window::' on member 'mousePressEvent'


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 01:21
и куда вы этот флаг поместили Qt::Tool ???


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 18, 2010, 01:22
Выкладываю весь проект. Попробуйте на его основе создать новое приложение в Qt(пустой проект GUI),добавьте туда файлы: systemtray.h , systemtray.cpp и в файл main.cpp перепишите соответствующий код. Создайте в папке с проектом папку images. В Qt добавьте файл ресурсов и назовите его images, добавьте в него приставку  /  теперь можно добавить файлы. Добавьте файл ёлочки и файл иконки(они должны быть в папке images). После сборки должно всё работать). На всякий случай добавьте картинки в папку с exe-шником(debug)   :)


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 18, 2010, 01:26
А вы случайно не знаете как всё в один exe-шник собрать,чтобы не таскать с собой библиотеки? ;)


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 01:41
я знаю как сделать установочный файл, можно будет его запустить, он установит его как программу и скажем на рабочем столе создаст лэйбл и само собой в пуске. а чтобы библиотеки статично компилировать - сам Qt говорит что нужно в .pro файле записать не помню точно что то типа -staticlib  но мне это не помогло. если вы в креаторе пишите то на сколько я нашел информации то все же придется его пересобирать что давольно таки проблемно, а вот как я вам сначала сказал способ - очень удобен, программа получается как заводская, длл устанавливаются на диск С и не мешаются))


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 01:44
так вы все же в debug собираете программу? нужно же в relise потому что debug несет в себе всю отладочную информации и дллки будут весить как вы заметили около 140 метров) а если соберете relise то около 10 и то если будете делать установочный файл как я говорил то он сожмет дллки и ехе в 4 метра


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 02:07
все же на эти строки ругается, без них работает но нельзя сдвинуть эконку которая на рабочем столе и какая то она серая получилась, не такая мигающая как должна))
    
Код:
    virtual void Window::mousePressEvent(QMouseEvent* pe)
    {
        m_ptPosition = pe->pos();
    }

    virtual void Window::mouseMoveEvent(QMouseEvent* pe)
    {
        move(pe->globalPos() - m_ptPosition);
    }


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 02:24
а ругался он потому что функции были описаны внутри класса, сделал так и все гуд, кроме того что елочка тупо серая. видимо .gif не поддерживается.

Код:
#include "window.h"
#include <QtGui>
class Window : public QLabel {
private:
    QPoint  m_ptPosition;

protected:
    virtual void mousePressEvent(QMouseEvent* pe);


    virtual void mouseMoveEvent(QMouseEvent* pe);

public:
    Window(QWidget* pwgt = 0)
        : QLabel(pwgt,  Qt::Tool)
    {
    }
};

void Window::mousePressEvent(QMouseEvent *pe)
{
    m_ptPosition = pe->pos();
}

void Window::mouseMoveEvent(QMouseEvent *pe)
{
    move(pe->globalPos() - m_ptPosition);
}



int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QApplication::setQuitOnLastWindowClosed(false);
    SystemTray   st;
    Window       win;
    QMovie       mov("elka.gif");
    QPixmap  pix(":/images/elka.gif");
    win.setMask(pix.mask());
    win.setMovie(&mov);
    win.resize(240,400);
    win.show();
    mov.start();
    QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Calc",
    QSettings::NativeFormat);
    qDebug()<< settings.value("layout").toString();
    settings.setValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Milkyway");
    settings.setValue("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\Galaxy\\Sun", "OurStar");
    settings.value("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\Galaxy\\Default"); // returns "Milkyway"
    return app.exec();
}



Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 02:27
ага проблема вот в чем была
Код:
QMovie       mov("elka.gif");
переделал

Код:
QMovie       mov(":/images/elka.gif");


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 02:30
а вы не знаете как ее сделать сварачиваемой? чтобы сликнув по иконке в трее елочка сворачивалась и разварачивалась...


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 18, 2010, 04:15
и вот посмотрите получился дистрибутив всего на 4 метра, конечно тоже не мало, но все же)

http://www.sendspace.com/file/5dp3nk (http://www.sendspace.com/file/5dp3nk)


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 19, 2010, 19:24
нет,это не потому что gif не поддерживает) картинку разместите в папке debug. Еще может быть из-за неправильных размеров под картинку,которые ты указываешь в строчке win.resize(240,400); ,где win - это объект класса унаследованный от QLabel.  Я в debug компилирую, ели в релиз то у меня и с библиотеками и без них сам exe-шник не запускается...


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 19, 2010, 19:26
По поводу тех строчек, может нужно было подключить файл #include <QMouseEvent>. У меня после этого не ругался)


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 19, 2010, 19:31
Я так дописала,чтобы ёлочка сварачивалась:
Код:
QAction* pactShowHide =
        new QAction("&Show/Hide Application Window", this);

    connect(pactShowHide, SIGNAL(triggered()),
            this,         SLOT(slotShowHide())
           );
И переделала проект слегка) Вот посмотри.


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 19, 2010, 19:38
скачала твой дистрибутив, но у меня почему-то ёлочка не отображается...
Вот что показывает.


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 19, 2010, 19:44
Расскажите мне,пожалуйста,как вы так сделали установочник?)) я так не умею..Но хочется научиться) Нужно специальную программку скачать для этого?


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 20, 2010, 01:13
ооо вот в том то и проблема что я сделал эту прогу, она у меня как нужно работает а у других как у вас не видет иконки)) хотя я их помещал в icon.qrc и они должны были вшиться в сам ехе файл))) обычно у меня так всегда с программами получается))
а такой установочник вообще очень просто делается, скачиваете программу excelsior installer, устанавливаете ее и потом остается лишь скопировать куда нибудь папку relese, закинуть в нее необходимые библиотеки - обычно это mingwm.dll, QtCore4.dll, QtGui4.dll, libgcc_s_dw2-1.dll . Затем жмете правой кнопкой мыши по папке релиз(лучшее ее переименовать к примеру elka) и выбираете пункт меню Build Package и за несколько секунд собирается вам установочный файлик .exe ) А ехе у вас не запускается потому что вы не положили библиотеки рядом с ехе) поэтому не забудьте поместить в папку релиз библиотеки которые я описал и только потом делайте Build Package.


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 20, 2010, 01:16
попробую закинуть в папку релиз эконки, может и в правду поможет) хотя по идее должно быть так как я описал выше)


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 20, 2010, 01:47
а вот еще что хотел спросить, у вас работает сохранение положения елки после закрытия программы? QSettings у меня почему то вообще не как не работает, я им ни разу не пользовался, но очень хочу научиться)


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 20, 2010, 01:50
ааа еще одно, а как у вас выглядит метод слот slotShowHide()???


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 20, 2010, 21:29
спасибо тебе большое!!)) буду пробовать)) Вот код слота:
Код:
void Window::slotShowHide()
{
    this->setVisible(!isVisible());
}
указатель this указывает на объект QLabel. Просто под старой версией,что я раньше выкладывала,может не заработать.) Я чуть выше новую выложила.
А про QSetings, я сама пыталась научиться им пользоваться..но пока безуспешно,это первые попытки. Код который написан там,это я хотела чтобы ёлочка добавлялась в реестр windows в автозапуск при старте windows. Но что-то у меня не сработало...На днях буду ещё пробовать.


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: eldar85 от Декабрь 21, 2010, 02:39
Спасибо большое) Как получиться добавлять в реестр дайте знать, тоже очень хочу научиться, делал несколько попыток но тоже безуспешно...


Название: Re: Как отображать программу только в области оповещения после запуска?
Отправлено: virtual_root от Декабрь 21, 2010, 11:50
оукей))