Skip to content

Instantly share code, notes, and snippets.

@namjae
Last active January 23, 2016 18:28
Show Gist options
  • Select an option

  • Save namjae/4b6b77a458ad25056246 to your computer and use it in GitHub Desktop.

Select an option

Save namjae/4b6b77a458ad25056246 to your computer and use it in GitHub Desktop.
Simple Notification Widget on Qt
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/**
* @file notifywindow.cpp
* @author M.W.Park <manywaypark@gmail.com>
* @date Thu Nov 20 11:31:12 2014
*
* @brief
*
* @note tested on windows 8.1, Qt 5.3 for now.
*/
#include <QDebug>
#include <QTimer>
#include <QApplication>
#include <QDesktopWidget>
#include "notifywindow.h"
#ifdef Q_OS_MAC
#include <Carbon/Carbon.h>
#endif
QVector<NotifyWindow *> NotifyWindow::windows_ = {};
int NotifyWindow::lastIdx_ = 0;
NotifyWindow::NotifyWindow(const QString &text, const int duration)
: QWidget(0 /* This zero is the first point */,
#ifdef Q_OS_MAC
Qt::SubWindow | // This type flag is the second point
#else
Qt::Tool |
#endif
Qt::FramelessWindowHint |
Qt::WindowSystemMenuHint |
Qt::WindowStaysOnTopHint),
size_(200, 100),
style_("background-color:yellow"),
margin_(10)
// : QWidget(QApplication::desktop())
{
setAttribute(Qt::WA_TranslucentBackground);
// And this conditional block is the third point
#ifdef Q_OS_MAC
winId(); // This call creates the OS window ID itself.
// qt_mac_window_for() doesn't
int setAttr[] = {
kHIWindowBitDoesNotHide, // Shows window even when app is hidden
kHIWindowBitDoesNotCycle, // Not sure if required, but not bad
kHIWindowBitNoShadow, // Keep this if you have your own design
// with cross-platform drawn shadows
0 };
int clearAttr[] = { 0 };
HIWindowChangeAttributes(qt_mac_window_for(this), setAttr, clearAttr);
#endif
label_ = new QLabel(this);
this->resize(size_);
label_->setWordWrap(true);
label_->setText(text);
label_->setStyleSheet(style_);
label_->setMargin(margin_);
qDebug() << "label: " << label_->geometry() << label_->pos();
qDebug() << "window:" << this->geometry() << this->pos();
QTimer::singleShot(duration, this, SLOT(close()));
this->autoPos();
windows_.append(this);
lastIdx_++;
}
void NotifyWindow::resize(int w, int h)
{
QWidget::resize(w, h);
label_->resize(w, h);
}
void NotifyWindow::resize(const QSize &size)
{
this->resize(size.width(), size.height());
}
bool NotifyWindow::close()
{
auto i = windows_.indexOf(this);
Q_ASSERT(i >= 0);
windows_.remove(i);
if (windows_.empty())
lastIdx_ = 0;
return QWidget::close();
}
void NotifyWindow::autoPos()
{
auto desktopRect = QApplication::desktop()->screenGeometry();
Q_ASSERT(this->width() <= desktopRect.width());
Q_ASSERT(this->height() <= desktopRect.height());
auto h_max = desktopRect.height() / this->height();
int x, y;
do {
x = desktopRect.width() - (((lastIdx_ / h_max) + 1) * this->width());
y = this->height() * (lastIdx_ % h_max);
if (x < 0) {
lastIdx_ = 0;
}
} while ( x < 0);
this->move(x, y);
}
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/**
* @file notifywindow.h
* @author M.W.Park <manywaypark@gmail.com>
* @date Thu Nov 20 11:31:50 2014
*
* @brief Simple Notification Widget
*
* @code{.cpp}
* // displays notification message (5 sec)
* NotifyWindow *w = new NotifyWindow("<b>title</b><br/>notification message", 5000);
* w->show();
* @endcode
*
* @ref http://stackoverflow.com/questions/5823700/notification-window-in-mac-with-or-without-qt
*
*/
#ifndef NOTIFYWINDOW_H
#define NOTIFYWINDOW_H
#include <QLabel>
#include <QVector>
#include <QWidget>
class NotifyWindow : public QWidget
{
Q_OBJECT
public:
/**
* ctor
*
* @param text notification message
* @param duration display duration in ms
*/
explicit NotifyWindow(const QString &text, const int duration);
void resize(int w, int h);
void resize(const QSize &);
signals:
public slots:
bool close();
private:
void autoPos();
private:
const QSize size_;
const QString style_;
const int margin_;
QLabel *label_;
private: // class variables
static QVector<NotifyWindow *> windows_;
static int lastIdx_;
};
#endif // NOTIFYWINDOW_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment