Qt窗口的标题栏自绘
2015-08-19 19:00
543 查看
因个人需要,要修改Qt Widget的标题栏,网上找了大半天,没有得到答案,但发现问的人比较多
所以现将找到的此文分享一下.
(原文:http://www.qtsoftware.com/developer/faqs/faq.2007-04-25.2011048382)
How can I handle events in the titlebar and change its color etc ?
(大概意思,也不知正不正确)
标题栏属于操作系统(控制),并且我们确实也没有控制它.你可以创建你自己的标题栏,但是这要花你很多精力.
为了创建你自己的包含最大化,最小化,关闭按钮,以及可以移动窗口的标题栏,你必须从QWidget派生一个子类.同时从
QFrame派生一个子类,为使些子类不要从窗口系统得到标题栏,设置Qt::FramelessWindowHint 窗口标记,
然而这又使得窗口不能通过窗口系统移动和缩放.
你可以将你自己的标题栏做为一个私有成员加到你的QFrame子类中,然后先将它添加到你的QFrame子类的垂直布局器中,
再在你的QFrame子类中添加一个content widget,以做为其它部件的容器(注:相当于窗口客户区).最后你的QFrame子类需要重载一些鼠标事件以控制窗口的缩放与移动.
下面的例子说明了它是怎样实现的.
转载地址:http://blog.csdn.net/litterflybug/article/details/4157482
所以现将找到的此文分享一下.
(原文:http://www.qtsoftware.com/developer/faqs/faq.2007-04-25.2011048382)
How can I handle events in the titlebar and change its color etc ?
Answer:
The titlebar belongs to the OS and we don't have control over that one. You can create your own titlebar, but note that this requires some work. In order to create your own titlebar then make a QWidget subclass that contains three toolbuttons that handle the close, minimize and maximize events in addition to the moving of the window. Then make a QFrame subclass which does not have a titlebar provided via the window system. This is done by setting the Qt::FramelessWindowHint window flag, however this will make it impossible to resize or move the window via the window system. What can be done is you can add your custom titlbar as a private member to the frame and add the it first to the frame's vertical layout. The frame also needs a content widget which allows widgets to be added to it. Finally the QFrame subclass needs to reimplement the mouse events to handle the resizing and moving of the window. The example below demonstrates how this can be achieved.(大概意思,也不知正不正确)
标题栏属于操作系统(控制),并且我们确实也没有控制它.你可以创建你自己的标题栏,但是这要花你很多精力.
为了创建你自己的包含最大化,最小化,关闭按钮,以及可以移动窗口的标题栏,你必须从QWidget派生一个子类.同时从
QFrame派生一个子类,为使些子类不要从窗口系统得到标题栏,设置Qt::FramelessWindowHint 窗口标记,
然而这又使得窗口不能通过窗口系统移动和缩放.
你可以将你自己的标题栏做为一个私有成员加到你的QFrame子类中,然后先将它添加到你的QFrame子类的垂直布局器中,
再在你的QFrame子类中添加一个content widget,以做为其它部件的容器(注:相当于窗口客户区).最后你的QFrame子类需要重载一些鼠标事件以控制窗口的缩放与移动.
下面的例子说明了它是怎样实现的.
#include <QApplication> #include <QtGui> #include <QLayout> #include <QStyle> class TitleBar : public QWidget { Q_OBJECT public: TitleBar(QWidget *parent) { // Don't let this widget inherit the parent's backround color setAutoFillBackground(true); // Use a brush with a Highlight color role to render the background setBackgroundRole(QPalette::Highlight); minimize = new QToolButton(this); maximize = new QToolButton(this); close= new QToolButton(this); // Use the style to set the button pixmaps QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton); close->setIcon(pix); maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton); maximize->setIcon(maxPix); pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton); minimize->setIcon(pix); restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton); minimize->setMinimumHeight(20); close->setMinimumHeight(20); maximize->setMinimumHeight(20); QLabel *label = new QLabel(this); label->setText("Window Title"); parent->setWindowTitle("Window Title"); QHBoxLayout *hbox = new QHBoxLayout(this); hbox->addWidget(label); hbox->addWidget(minimize); hbox->addWidget(maximize); hbox->addWidget(close); hbox->insertStretch(1, 500); hbox->setSpacing(0); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); maxNormal = false; connect(close, SIGNAL( clicked() ), parent, SLOT(close() ) ); connect(minimize, SIGNAL( clicked() ), this, SLOT(showSmall() ) ); connect(maximize, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) ); } public slots: void showSmall() { parentWidget()->showMinimized(); } void showMaxRestore() { if (maxNormal) { parentWidget()->showNormal(); maxNormal = !maxNormal; maximize->setIcon(maxPix); } else { parentWidget()->showMaximized(); maxNormal = !maxNormal; maximize->setIcon(restorePix); } } protected: void mousePressEvent(QMouseEvent *me) { startPos = me->globalPos(); clickPos = mapToParent(me->pos()); } void mouseMoveEvent(QMouseEvent *me) { if (maxNormal) return; parentWidget()->move(me->globalPos() - clickPos); } private: QToolButton *minimize; QToolButton *maximize; QToolButton *close; QPixmap restorePix, maxPix; bool maxNormal; QPoint startPos; QPoint clickPos; };
class Frame : public QFrame { public: Frame() { m_mouse_down = false; setFrameShape(Panel); // Make this a borderless window which can't // be resized or moved via the window system setWindowFlags(Qt::FramelessWindowHint); setMouseTracking(true); m_titleBar = new TitleBar(this); m_content = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(this); vbox->addWidget(m_titleBar); vbox->setMargin(0); vbox->setSpacing(0); QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(m_content); layout->setMargin(5); layout->setSpacing(0); vbox->addLayout(layout); } // Allows you to access the content area of the frame // where widgets and layouts can be added QWidget *contentWidget() const { return m_content; } TitleBar *titleBar() const { return m_titleBar; } void mousePressEvent(QMouseEvent *e) { m_old_pos = e->pos(); m_mouse_down = e->button() == Qt::LeftButton; } void mouseMoveEvent(QMouseEvent *e) { int x = e->x(); int y = e->y(); if (m_mouse_down) { int dx = x - m_old_pos.x(); int dy = y - m_old_pos.y(); QRect g = geometry(); if (left) g.setLeft(g.left() + dx); if (right) g.setRight(g.right() + dx); if (bottom) g.setBottom(g.bottom() + dy); setGeometry(g); m_old_pos = QPoint(!left ? e->x() : m_old_pos.x(), e->y()); } else { QRect r = rect(); left = qAbs(x - r.left()) <= 5; right = qAbs(x - r.right()) <= 5; bottom = qAbs(y - r.bottom()) <= 5; bool hor = left | right; if (hor && bottom) { if (left) setCursor(Qt::SizeBDiagCursor); else setCursor(Qt::SizeFDiagCursor); } else if (hor) { setCursor(Qt::SizeHorCursor); } else if (bottom) { setCursor(Qt::SizeVerCursor); } else { setCursor(Qt::ArrowCursor); } } } void mouseReleaseEvent(QMouseEvent *e) { m_mouse_down = false; } private: TitleBar *m_titleBar; QWidget *m_content; QPoint m_old_pos; bool m_mouse_down; bool left, right, bottom; };
#include "main.moc" int main(int argc, char **argv) { QApplication app(argc, argv); Frame box; box.move(0,0); QVBoxLayout *l = new QVBoxLayout(box.contentWidget()); l->setMargin(0); QTextEdit *edit = new QTextEdit(box.contentWidget()); l->addWidget(edit); box.show(); return app.exec(); }
转载地址:http://blog.csdn.net/litterflybug/article/details/4157482
相关文章推荐
- 学习记录-Qt在win7下安装opencv库
- win7下Qt Creator使用Gsoap
- Qt下使用的静态链接库------ *.lib转化为mingw使用的.a格式的静态库
- Qt学习之路【1】:QT显示中文问题
- 在Qt使用moveToThread() qt的线程
- QT 中控件缩放比列设置
- MAC 平台使用qt 静态链接boost 库问题
- QT 正则表达式
- QT window xp 下打不开文件对话框解决
- QT跨线程的信号与槽
- qt控件认知之布局控件
- Windows 安装Qt+VS2010/MinGW
- Qt 技术积累
- windows下配置qwt开发环境
- Qt qDebug() 的使用方法
- Qt5.2连接SQLServer2008
- QT QMessageBox添加中文按钮
- Qt之打包发布(NSIS详解)(转)
- QT串口工具(3)
- QT串口工具(2)