Russian Qt Forum

Qt => Кладовая готовых решений => Тема начата: Vitto74 от Февраль 12, 2011, 13:55



Название: Всплывающие уведомления
Отправлено: Vitto74 от Февраль 12, 2011, 13:55
Хочу поделится кодом, реализующим всплывающие сообщения на подобии тех, которые используются в IM клиентах. Код несколько сыроват, но допилить его под что угодно не составит труда.
Лицензия LGPL - пользуйтесь для любых целей, но измененные исходники модуля предоставьте пользователям.
Комменты на русском в кодировке UTF-8.
Код:
#include "popupmessage.h"

...

    //index - произвольные данные (см. исходник)
    PManager::addMessage(title, message, index);


Название: Re: Всплывающие уведомления
Отправлено: navrocky от Февраль 15, 2011, 15:57
Цитировать
Код несколько сыроват
Да.

Код
C++ (Qt)
this->setWindowFlags(Qt::ToolTip);
this->index = index;
delete this->messages[0];
 
Вспомнился писон  ;D

Код:
//Если объект просто уничтожить возникнет ошибка, т.к.
//мы уничтожаем самого себя. Поэтому скращаем время жизни до 50
//милисекунд
есть метод QObject::deleteLater().

Код
C++ (Qt)
static popupManager* getObj(){static popupManager *instance = new popupManager(); return instance;};
 
небольшая утечка в синглтоне.

Код:
//Переменная int index - это произвользые данные, которые передаются объекту при созданни.
//Тип может быть любым
Смысл этого не ясен, зачем? В смысле, ясно, что это что-то типа поля QVariant data(). Но зачем оно там?

Ну что еще сказать.. бывает оно такое и надо. Есть еще системный нотификатор в линупсах, его можно опционально юзать внутри твоей либы.


Название: Re: Всплывающие уведомления
Отправлено: Vitto74 от Февраль 15, 2011, 16:14
Код
C++ (Qt)
this->setWindowFlags(Qt::ToolTip);
this->index = index;
delete this->messages[0];
 
Вспомнился писон  ;D

У меня такого кода там нет.

Код:
//Если объект просто уничтожить возникнет ошибка, т.к.
//мы уничтожаем самого себя. Поэтому скращаем время жизни до 50
//милисекунд
есть метод QObject::deleteLater().

Блин. Я еще так долго в этот участок кода втыкал - знал, что так не правильно, но так и не дошло что тут deleteLater использовать нужно.

Код
C++ (Qt)
static popupManager* getObj(){static popupManager *instance = new popupManager(); return instance;};
 
небольшая утечка в синглтоне.

Где именно? Я не очень хорошо в них разбираюсь.

Код:
//Переменная int index - это произвользые данные, которые передаются объекту при созданни.
//Тип может быть любым
Смысл этого не ясен, зачем? В смысле, ясно, что это что-то типа поля QVariant data(). Но зачем оно там?

В моей софтине, при клике, показывается главное окно с той вкладкой, которая вызвала появление уведомления. Мне достаточно int, но может так статься, что int будет мало для реагирования на клик мыши.


Название: Re: Всплывающие уведомления
Отправлено: Racheengel от Февраль 17, 2011, 01:36
насчет лика в синглтоне: поскольку статик поинтер аллоцируется и инициализируется через new, то его некому будет прибить по завершению проги. Ибо деструктор не вызовется. Лучше так сделать:

Код:
static popupManager* getObj()
{
    static popupManager instance;
    return &instance;
}


Название: Re: Всплывающие уведомления
Отправлено: navrocky от Февраль 18, 2011, 09:21
Код
C++ (Qt)
this->setWindowFlags(Qt::ToolTip);
this->index = index;
delete this->messages[0];
 
Вспомнился писон  ;D
У меня такого кода там нет.
Это копипаста из разных частей кода, но у тебя там все усеяно обращением к своим методам и переменым через this, как будто ты не знаешь что this-> - это лишнее...

В моей софтине, при клике, показывается главное окно с той вкладкой, которая вызвала появление уведомления. Мне достаточно int, но может так статься, что int будет мало для реагирования на клик мыши.
Ну как я и писал ранее, QVariant в этом случае лучше.


Название: Re: Всплывающие уведомления
Отправлено: kuzulis от Февраль 18, 2011, 10:45
Цитировать
как будто ты не знаешь что this-> - это лишнее...
Ну, я б не стал так категорично заявлять.
Вот я к примеру наоборот, предпочитаю ставить this чтобы не путать чей это метод, ИМХО, так нагляднее.  :)


Название: Re: Всплывающие уведомления
Отправлено: navrocky от Февраль 19, 2011, 01:11
Цитировать
как будто ты не знаешь что this-> - это лишнее...
Ну, я б не стал так категорично заявлять.
Вот я к примеру наоборот, предпочитаю ставить this чтобы не путать чей это метод, ИМХО, так нагляднее.  :)
Мне ни разу не приходилось так выделять. Обычно свои методы зову напрямую, чужие по указателю или ссылке. Вроде все наглядно. Функции почти не использую.


Название: Re: Всплывающие уведомления
Отправлено: serg_hd от Февраль 22, 2011, 22:11
Цитировать
как будто ты не знаешь что this-> - это лишнее...
Ну, я б не стал так категорично заявлять.
Вот я к примеру наоборот, предпочитаю ставить this чтобы не путать чей это метод, ИМХО, так нагляднее.  :)
Согласен, тоже всегда так делаю.

Мне ни разу не приходилось так выделять. Обычно свои методы зову напрямую, чужие по указателю или ссылке. Вроде все наглядно. Функции почти не использую.
Тогда ответь, mymethod() - это чей метод, класса MyClass или он вообще не принадлежит никому (описан вне класса)? ;):
Код
C++ (Qt)
void MyClass::doit()
{
mymethod();
}
 

this намного повышает удобочитаемость. Другое дело, когда люди наследуют Class1 классом Class2 и вызывают Class1::method() в классе Class2 (в котором нет перегруженного method()) через this, так делать не надо.


Название: Re: Всплывающие уведомления
Отправлено: asvil от Февраль 22, 2011, 22:21
serg_hd, Вы привели код, в котором возможны только два следующих варианта:
Если вызов без this - это член этого класса. Поправлено
Если вызов без this - это статическая функция. Поправлено
Теперь давайте перечислим ситуации когда используются статические функции и мне кажется, что мы сможем четко определить, что названия методов и функций будут разительно отличаться. И вообще что это там за функции у кого-то в ООП? А ну-ка признавайтесь кто тут занимается функциональным программированием?
Хотя у нас на работе решили все статические функции обернуть пространствами имен. Голоса: трое к одному.

Чаще всего статические функции и классы смешиваются при написании ООП оберток для стабильных библиотек. А в стабильных библиотеках используется префиксная идентификация, например PGgetResult.

P.S. Прошу прощения, сначала хотел написать что-то, что уже не помню. Потом удалил, но слово "ничего" не удалил.
P.P.S. Статическая функция - это я зря сказал "статическая". Имел ввиду..эм.."глобальная", ну вообщем просто функция.


Название: Re: Всплывающие уведомления
Отправлено: serg_hd от Февраль 22, 2011, 22:31
Если метод без ничего this это член этого класса.
Если метод без ничего this это статическая функция.
Честно признаться, мало что из этого понял, напоминает "казнить нельзя помиловать" (знаки препинания расставьте сами)???
this - это вообще-то указатель на объект класса, а статическая функция не "без ничего" а с ключ. словом "static". Тем static-определения и отличаются от не статических, что static существуют в единственном экземпляре и вы не получите всяких "multiple definition", например если метод описан в .h и этот .h не единожды инклудится. И вообще, что значит "метод без ничего"?


Название: Re: Всплывающие уведомления
Отправлено: ритт от Февраль 22, 2011, 23:08
да, знаки препинания нынче совершенно вышли из моды...

но как бы то ни было, Михаил правильно сказал - префиксная идентификация для функций (опционально, в пространстве имён), инлайны где только возможно (но в меру, конечно же :P ), this - там, где нужен указатель на "данный объект".
я бы сказал - "Голоса: четверо к одному." :)

а вообще, это из той же песни, что и "ставить virtual перед методами классов-наследников или опускать?" - должно определяться внешними или внутренними правилами для всех разработчиков проекта - дабы поддерживать код в чистоте; иного профита в этом нет...


Название: Re: Всплывающие уведомления
Отправлено: navrocky от Февраль 24, 2011, 11:38
Ну если все-таки придерживаться языка C++, то в нем обычных функций крайне мало, поэтому, this это все-таки перебор.

Кстати, раз уж всплыло, интересны мнения остальных по этому вопросу:
Цитировать
Ставить virtual перед методами классов-наследников или опускать?
Я у себя проставляю virtual, хотя интуитивно и без особых оснований... может для наглядности, когда смотришь на код наследника...


Название: Re: Всплывающие уведомления
Отправлено: ритт от Февраль 24, 2011, 13:14
> Я у себя проставляю virtual, хотя интуитивно и без особых оснований... может для наглядности, когда смотришь на код наследника...
с другой стороны, бегай потом смотри у какого класса впервые данный виртуал появился

но это уже оффтоп - создавайте тему в говорилке, например.


Название: Re: Всплывающие уведомления
Отправлено: Странник от Август 05, 2011, 15:48
понадобилось реализовать эту приблуду, набросал свой вариант, может пригодится кому. критика приветствуется.
тем и либ плодить не стал, уж извините.

p.s.
поддерживается html-форматирование, гиперссылки, кастомные виджеты сообщений.


Название: Re: Всплывающие уведомления
Отправлено: SeverusSnape от Август 05, 2011, 17:24
http://dl.dropbox.com/u/6896945/prettyosd.zip

Pretty OSD из Clementine Player


Название: Re: Всплывающие уведомления
Отправлено: Rem Norton от Сентябрь 09, 2011, 23:47
Мои 5 копеек: (может кому пригодится)
Писал как-то давно для одного проектика, для людей не жалко.

Класс в приложении.
Интерфейс:
Код:
static void info(const QString& title,const QString& msg,const QPoint& point, int delay = 0, bool bShowArrow = true, bool bArrowDown = true);
static void critical(const QString& title,const QString& msg,const QPoint& point, int delay = 0, bool bShowArrow = true, bool bArrowDown = true);
static void warning(const QString& title,const QString& msg,const QPoint& point, int delay = 0, bool bShowArrow = true, bool bArrowDown = true);

где:
title - заголовок
msg - текст сообщения
delay - задержка (мсек)
bShowArrow - показывать стрелку
bArrowDown - если true, то стрелка вниз, иначе - вверх. Если bShowArrow = false, то по барабану  ;D
point - точка, около которой будет отрисован виджет. Если bShowArrow == bArrowDown == true, то point - точка в которую укажет стрелка.

Пример вызова:
Код:
// Сначала собираем строку (если нужно)

        errorMess.clear();
bool bRes = true ;
if (cbClients->currentIndex() <0)
{
errorMess +=QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px\"><span style=\"color:#ff0000;\"><b> %1</b></span>%2</p>").arg(QApplication::tr("-Customer")).arg(QApplication::tr(" should be chosen"));
bRes = false;
};
if (cbFaces->currentIndex() <0)
{
errorMess +=QString("<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px\"><span style=\"color:#ff0000;\"><b> %1</b></span>%2</p>").arg(QApplication::tr("-Representative of customer")).arg(QApplication::tr(" should be chosen"));
bRes = false;
}
if (!bRes) errorMess = "<style type=\"text/css\">p, li { white-space: pre-wrap; }</style>" + errorMess ;
...
...
// Потом отображаем
QBubbleTip::warning(QApplication::tr("Errors:"),errorMess,mapToGlobal(QPoint(10,10)));

На экране видим такое:

(http://img13.imageshost.ru/img/2011/09/10/image_4e6a7b278171b.png) (http://imageshost.ru/)

Ну вот как-то так...