Да. Вы правильно думаете. Ну немогу найти пример...
- скруглённое окно
- тонкая кнопка закрытия
Наконец-то руки дошли
Ты наверно и сам уже разобрался, но вдруг другим понадобится
Воощем вот код виджета с самодельным заголовком
roundWidget.h
C++ (Qt)
#ifndef ROUNDWIDGET_H
#define ROUNDWIDGET_H
#include <QWidget>
class QLabel;
class QToolButton;
class QVBoxLayout;
class RoundWidget : public QWidget
{
public:
RoundWidget(QWidget *content, QWidget *parent = 0, Qt::WindowFlags f = 0);
~RoundWidget();
// функция заголовочного текста и иконки
void setWidgetTitle(const QString &text, const QPixmap &pixmap = QPixmap());
// функция установки заливки загаловка
void setFillGradientTitle(const QColor &color1, const QColor &color2);
protected:
void resizeEvent(QResizeEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
private:
QWidget *widgetTitle_; // Заголовок окна
QLabel *labelTitleIcon_; // Иконка загаловка окна
QLabel *labelTitleText_; // Текст загаловка окна
QToolButton *btnClose_; // Кнопка закрытия окна
QPoint dragPosition_;
};
#endif // ROUNDWIDGET_H
roundWidget.cpp
C++ (Qt)
#include "roundWidget.h"
#include <QLabel>
#include <QPixmap>
#include <QPainter>
#include <QBitmap>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QApplication>
#include <QMouseEvent>
RoundWidget::RoundWidget(QWidget *content, QWidget *parent, Qt::WindowFlags flags)
: QWidget(parent, flags)
{
setMouseTracking(true);
QVBoxLayout *layoutWindow = new QVBoxLayout(this);
layoutWindow->setMargin(0);
layoutWindow->setSpacing(0);
layoutWindow->setAlignment(Qt::AlignTop);
// Создание заголовка окна
widgetTitle_ = new QWidget(this);
widgetTitle_->setAutoFillBackground(true);
widgetTitle_->setFixedHeight(16);
QHBoxLayout *layTitle = new QHBoxLayout(widgetTitle_);
layTitle->setMargin(2);
layTitle->setSpacing(0);
labelTitleIcon_ = new QLabel(widgetTitle_);
labelTitleText_ = new QLabel(widgetTitle_);
labelTitleText_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
labelTitleText_->setMouseTracking(true);
labelTitleText_->installEventFilter(this);
QPushButton *btnClose = new QPushButton(widgetTitle_);
btnClose->setFixedSize(8,8);
btnClose->setIcon(QIcon(QApplication::applicationDirPath() + "/close.png"));
// close.png - нарисованный в фотошопе крестик с прозрачным фоном
layTitle->addWidget(labelTitleIcon_);
layTitle->addWidget(labelTitleText_);
layTitle->addWidget(btnClose);
bool connectSS = false; // test connection SIGNAL - SLOT
connectSS = connect(btnClose, SIGNAL(clicked()), this, SLOT(close())); // закрытие окна по нашей кнопке
Q_ASSERT(connectSS);
layoutWindow->addWidget(widgetTitle_);
if (content) { // виджет содержимого окна
layoutWindow->addWidget(content);
}
resize(minimumSizeHint());
}
RoundWidget::~RoundWidget()
{
}
void RoundWidget::setWidgetTitle(const QString &text, const QPixmap &pixmap)
{
labelTitleText_->setText(text);
labelTitleIcon_->setPixmap(pixmap);
}
void RoundWidget::setFillGradientTitle(const QColor &color1, const QColor &color2)
{
QLinearGradient gradient(0, 0, 0, widgetTitle_->height());
gradient.setColorAt(0.0, color1);
gradient.setColorAt(1.0, color2);
QPalette pal = widgetTitle_->palette();
QBrush br = pal.brush(QPalette::Button);
pal.setBrush(QPalette::Window, QBrush(gradient));
pal.setBrush(QPalette::Button, color2);
widgetTitle_->setPalette(pal);
}
bool RoundWidget::eventFilter(QObject *obj, QEvent *event)
{
QMouseEvent *e = 0;
if (obj == labelTitleText_ && (e = dynamic_cast<QMouseEvent *>(event))) {
// перепещение окна
if (e->type() == QEvent::MouseButtonPress && e->button() == Qt::LeftButton) {
dragPosition_ = e->globalPos() - frameGeometry().topLeft();
e->accept();
} else if (e->type() == QEvent::MouseMove && (e->buttons() & Qt::LeftButton)) {
move(e->globalPos() - dragPosition_);
e->accept();
}
return true;
}
return QObject::eventFilter(obj, event);
}
void RoundWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
QRect r = rect();
// делаем маску с закругленными краями под размер окна
QPixmap pix(r.size());
pix.fill(Qt::transparent);
QPainter p(&pix);
p.setBrush(Qt::black);
p.drawRoundRect(r, 5, 5);
setMask(pix.mask());
}
main.cpp
#include <QApplication>
#include <QPushButton>
#include "roundWidget.h"
C++ (Qt)
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QApplication::setStyle("Plastique");
QPushButton *content = new QPushButton();
content->setText("Button");
content->setFixedSize(500, 200);
RoundWidget rw(content);
rw.setWidgetTitle("Tram param param", QPixmap(QApplication::applicationDirPath() + "/ai.png").scaled(12,12));
rw.setFillGradientTitle(Qt::white, Qt::magenta);
//rw.setFixedSize(300, 200);
rw.show();
return a.exec();
}
Собственно суть в следующем.
1) Создание собственного заголовка окна (у меня в конструкторе)
Состоит из двух лайблов
labelTitleIcon_ - иконка окна
widgetTitle_ - имя окна
и кнопки закрытия
btnClose
В конструктор у меня передается виджет с тем, что должно быть в окне.
2) Наложение маску на виджет
Это происходит в перегруженной функции
void RoundWidget::resizeEvent(QResizeEvent *event)
там все просто
3) Реализация перемещения окна
перегруженная функция
bool RoundWidget::eventFilter(QObject *obj, QEvent *event)
тут ловятся события мыши, которые происходят на лайбле с именем окна, и перемещяется окно на заданную позицию
Остальное для красоты
С деталями нужно поиграться, чтоб до ума довести