Qt中QDockWidget的自定义标题栏

本例有Qt的官网例子改写而来。效果如下:

具体代码如下

头文件

#ifndef CDOCWIDGETBAR_H
#define CDOCWIDGETBAR_H

#include <QWidget>


class CDocWidgetBar : public QWidget
{
	Q_OBJECT

public:
	CDocWidgetBar(QWidget *parent = 0);
	~CDocWidgetBar();

	QSize sizeHint() const { return minimumSizeHint(); }
	QSize minimumSizeHint() const;
protected:
	void paintEvent(QPaintEvent *event);
	void mousePressEvent(QMouseEvent *event);
	public slots:
		void updateMask();

private:
	QPixmap leftPm, centerPm, rightPm;

};

#endif // CDOCWIDGETBAR_H

cpp文件

#include "cdocwidgetbar.h"
#include <QDockWidget>
#include <QPainter>
#include <QMouseEvent>
#include <QBitmap>

CDocWidgetBar::CDocWidgetBar(QWidget *parent)
	: QWidget(parent)
{
	leftPm = QPixmap(":/docwidgetaddtitle/image/titlebarLeft.png");
	centerPm = QPixmap(":/docwidgetaddtitle/image/titlebarCenter.png");
	rightPm = QPixmap(":/docwidgetaddtitle/image/titlebarRight.png");
}

CDocWidgetBar::~CDocWidgetBar()
{

}
QSize CDocWidgetBar::minimumSizeHint() const
{
	QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget());
	Q_ASSERT(dw != 0);
	QSize result(leftPm.width() + rightPm.width(), centerPm.height());
	if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar)
		result.transpose();
	return result;
}

void CDocWidgetBar::paintEvent(QPaintEvent*)
{
	QPainter painter(this);
	QRect rect = this->rect();

	QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget());
	Q_ASSERT(dw != 0);

	if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) {
		QSize s = rect.size();
		s.transpose();
		rect.setSize(s);

		painter.translate(rect.left(), rect.top() + rect.width());
		painter.rotate(-90);
		painter.translate(-rect.left(), -rect.top());
	}

	painter.drawPixmap(rect.topLeft(), leftPm);
	painter.drawPixmap(rect.topRight() - QPoint(rightPm.width() - 1, 0), rightPm);
	QBrush brush(centerPm);
	painter.fillRect(rect.left() + leftPm.width(), rect.top(),
		rect.width() - leftPm.width() - rightPm.width(),
		centerPm.height(), centerPm);
}

void CDocWidgetBar::mousePressEvent(QMouseEvent *event)
{
	QPoint pos = event->pos();

	QRect rect = this->rect();

	QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget());
	Q_ASSERT(dw != 0);

	if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) {
		QPoint p = pos;
		pos.setX(rect.left() + rect.bottom() - p.y());
		pos.setY(rect.top() + p.x() - rect.left());

		QSize s = rect.size();
		s.transpose();
		rect.setSize(s);
	}

	const int buttonRight = 7;
	const int buttonWidth = 20;
	int right = rect.right() - pos.x();
	int button = (right - buttonRight)/buttonWidth;
	switch (button) {
		case 0:
			event->accept();
			dw->close();
			break;
		case 1:
			event->accept();
			dw->setFloating(!dw->isFloating());
			break;
		case 2: {
			event->accept();
			QDockWidget::DockWidgetFeatures features = dw->features();
			if (features & QDockWidget::DockWidgetVerticalTitleBar)
				features &= ~QDockWidget::DockWidgetVerticalTitleBar;
			else
				features |= QDockWidget::DockWidgetVerticalTitleBar;
			dw->setFeatures(features);
			break;
				}
		default:
			event->ignore();
			break;
	}
}

void CDocWidgetBar::updateMask()
{
	QDockWidget *dw = qobject_cast<QDockWidget*>(parent());
	Q_ASSERT(dw != 0);

	QRect rect = dw->rect();
	QPixmap bitmap(dw->size());

	{
		QPainter painter(&bitmap);

		///initialize to transparent
		painter.fillRect(rect, Qt::color0);

		QRect contents = rect;
		contents.setTopLeft(geometry().bottomLeft());
		contents.setRight(geometry().right());
		contents.setBottom(contents.bottom()-y());
		painter.fillRect(contents, Qt::color1);



		//let's pait the titlebar

		QRect titleRect = this->geometry();

		if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) {
			QSize s = rect.size();
			s.transpose();
			rect.setSize(s);

			QSize s2 = size();
			s2.transpose();
			titleRect.setSize(s2);

			painter.translate(rect.left(), rect.top() + rect.width());
			painter.rotate(-90);
			painter.translate(-rect.left(), -rect.top());
		}

		contents.setTopLeft(titleRect.bottomLeft());
		contents.setRight(titleRect.right());
		contents.setBottom(rect.bottom()-y());

		QRect rect = titleRect;


		painter.drawPixmap(rect.topLeft(), leftPm.mask());
		painter.fillRect(rect.left() + leftPm.width(), rect.top(),
			rect.width() - leftPm.width() - rightPm.width(),
			centerPm.height(), Qt::color1);
		painter.drawPixmap(rect.topRight() - QPoint(rightPm.width() - 1, 0), rightPm.mask());

		painter.fillRect(contents, Qt::color1);
	}

	dw->setMask(bitmap);
}

使用代码如下

CDocWidgetBar *titlebar = new CDocWidgetBar(ui.dockWidget);

    ui.dockWidget->setTitleBarWidget(titlebar);
    ui.dockWidget->setMinimumWidth(481);
    ui.dockWidget->setMinimumHeight(335);
    ui.dockWidget->resize(481, 350);

    connect(ui.dockWidget, SIGNAL(topLevelChanged(bool)), titlebar, SLOT(updateMask()));
    connect(ui.dockWidget, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures)), titlebar, SLOT(updateMask()), Qt::QueuedConnection);

问题:好像不能修改高度,有待解决。。。。。

发布了85 篇原创文章 · 获赞 34 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/chyuanrufeng/article/details/99973272
今日推荐