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

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

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Тень в Qt  (Прочитано 16145 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #15 : Октябрь 05, 2010, 19:03 »

Как оказалось в результате более близкого рассмотрения тень в Qt как для диалоговых окон так и для любого top-level widget реализуется довольно просто без танцев с бубном и без новых навороченных возможностей.
Да и почему-бы это было невозможным? В Qt есть все для этого средства...
(Qt::FramelessWindowHint, Qt::SplashScreen, QWidget::setMask(), QWidget::setOpacity()).  Смеющийся
Ну "замах" явно рублевый  Улыбающийся А вот какой будет "бросок" - не копеечный ли? Показываем..
Записан
offitserov
Гость
« Ответ #16 : Октябрь 10, 2010, 19:40 »

Доброго времени суток.
Простите что сразу не запостил пример, не было времени.
Также сразу хочу оговориться:
1. Пример не показывает как сделать передачу сообщений окнам под тенью, это не кроссплатформенный заход.
2. Не тестировал под Линуксом, судя по отзывам могут быть проблемы с прозрачностью.
3. Таже пример есть просто концепт, призванный показать что возможность нарисовать тень есть и работает "as-is". Например красивее тень рисовать градиентами и обрабатывать некоторые события по-чище.
Код:
#include <QtGui>
//------------------------------------------------------------------
class ShadowWidget : public QWidget
{
public:
    ShadowWidget(QWidget * nestedWidget, QWidget *parent = 0, int shadowWidth = 10, int radius = 5)
        : QWidget(parent, Qt::SplashScreen)
        , m_nested(nestedWidget)
        , m_shadowWidth(shadowWidth)
        , m_radius(radius)
    {
        this->setWindowOpacity(0.4);
    }

    void updateSize()
    {
        move(m_nested->pos());
        setFixedSize(m_nested->size().width() + m_shadowWidth, m_nested->size().height() + m_shadowWidth);
    }

protected:
    void paintEvent       (QPaintEvent  *event)
    {
        Q_UNUSED(event);
        QPainter painter(this);
        painter.fillRect(rect(), QBrush(Qt::black));
    }

    void resizeEvent      (QResizeEvent *event)
    {
        qDebug() << Q_FUNC_INFO << " pos() = " << pos();
        Q_UNUSED(event);
        QBitmap bitmap(rect().size());
        bitmap.fill(Qt::white);
        bitmap.createMaskFromColor(Qt::white, Qt::MaskOutColor);
        QPainter painter(&bitmap);
       
        QPainterPath opaquePath;
        opaquePath.addRoundRect(rect().adjusted(m_shadowWidth, m_shadowWidth, 0, 0), m_shadowWidth, m_shadowWidth);
        painter.fillPath(opaquePath, Qt::black);

        QPainterPath transparentPath;
        transparentPath.addRoundRect(rect().adjusted(0, 0, -m_shadowWidth, -m_shadowWidth), m_radius, m_radius);
        painter.fillPath(transparentPath, Qt::white);
       
        setMask(bitmap);
    }

private:
    QWidget *m_nested;
    int m_shadowWidth;
    int m_radius;
};
//------------------------------------------------------------------
class CustomDialog : public QDialog
{
Q_OBJECT
public:

    CustomDialog(QWidget *parent = 0, int radius = 5)
        : QDialog(parent, Qt::FramelessWindowHint)
        , m_shadow(new ShadowWidget(this, parent))
        , m_radius(radius)
    {
    }

    ~CustomDialog()
    {
        delete m_shadow;
    }
   
protected:
/// event handlers
    void mousePressEvent  (QMouseEvent  *event)
    {
        const bool leftButtonPressed(event->button() == Qt::LeftButton);
        if (!leftButtonPressed || !rect().contains(event->pos()))
            return;
        m_moving = true;
        m_dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
        return;
    }

    void mouseReleaseEvent(QMouseEvent  *event)
    {
        Q_UNUSED(event);
        m_moving = false;
    }

    void mouseMoveEvent   (QMouseEvent  *event)
    {
        if (!m_moving)
            return;

        move(event->globalPos() - m_dragPosition);
        m_shadow->updateSize();
        m_dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
    }

void paintEvent       (QPaintEvent  *event)
    {
        Q_UNUSED(event);
        QPainter painter(this);
        QPen pen(QColor(Qt::green), 3);
        painter.setPen(pen);
        painter.drawRoundRect(rect().adjusted(0, 0, -1, -1), m_radius, m_radius);
        m_shadow->updateSize();
        m_shadow->show();
    }

    void resizeEvent      (QResizeEvent *event)
    {
        Q_UNUSED(event);
        QBitmap bitmap(rect().size());
        bitmap.fill(Qt::white);
        bitmap.createMaskFromColor(Qt::white, Qt::MaskOutColor);
        QPainter painter(&bitmap);
        painter.setPen(Qt::black);
        QPainterPath path;
        path.addRoundRect(rect(), m_radius, m_radius);
        painter.fillPath(path, Qt::black);
        setMask(bitmap);
        m_shadow->update();
    }

private:

bool m_moving;
QPoint           m_dragPosition;
    ShadowWidget *m_shadow;
    int m_radius;
};
//------------------------------------------------------------------
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    CustomDialog dialog;
    dialog.setFixedSize(100, 60);
    dialog.show();
    app.exec();
}

#include "main.moc"
Пользуйтесь на здоровье. Улыбающийся
Записан
SASA
Гость
« Ответ #17 : Октябрь 11, 2010, 10:35 »

Код:
void paintEvent       (QPaintEvent  *event)
{
m_shadow->updateSize();
m_shadow->show();
}

void resizeEvent      (QResizeEvent *event)
{
m_shadow->update();
}
А Зачем эти строки?
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


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