因个人需要,要修改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 ?

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窗口的标题栏自绘的更多相关文章

  1. Qt编程—去掉标题栏和设置窗口透明用法

    学习Qt编程,有时候我们很想做出好看又比较炫的画面,这时就常用到qt上的一些技巧. 这里我以一个小例子来展示qt的这些技巧,此qt编程写的,如图:(去掉标题栏和设置窗口透明后) 代码实现部分: .h文 ...

  2. Qt之去除窗口的标题栏、通过鼠标移动窗口

    设置标题栏图标,位置与大小示例 #include<QApplication> #include<QWidget> #include<QDebug> #include ...

  3. 调色板类QPalette——包含了Qt窗口不见的颜色组(collor group),和Windows右键属性外观非常类似

    QPalette类包含了Qt窗口不见的颜色组(collor group); 1.Active组,该组的颜色用户当前活动的(active)窗口,即具有键盘或鼠标焦点的窗口; 2.Inactive组,该组 ...

  4. Qt窗口定制

    qt中的QWidget窗口支持窗体绘制,但是不支持窗口标题栏绘制,想要美观的界面,还需要自己去定制,下面我就介绍一种定制窗体的方法 一个窗口无非就3部分,标题栏.窗体和状态栏,接下来我定制的窗口没有状 ...

  5. QT 窗口拖拽移动实现

    我们知道,要实现窗口移动可以直接鼠标点住窗口的标题栏实现拖拽移动,这是窗口默认的行为,在QT中的事件响应函数为moveEvent. 但是现实中经常需要鼠标点住窗口客户区域实现窗口的拖拽移动,代码实现如 ...

  6. [DForm]我也来做自定义Winform之另类标题栏重绘

    据说得有楔子 按照惯例,先来几张样例图(注:为了展示窗口阴影效果,截图范围向外扩展了些,各位凭想象吧).                   还要来个序 其实,很多年没写过Winform了,前端时间在 ...

  7. 自定义QT窗口部件外观之QStyle

    自定义QT窗口部件外观 重新定义Qt内置窗口部件的外观常用的方法有两种:一是通过子类化QStyle 类或者预定义的一个样式,例如QWindowStyle,来定制应用程序的观感:二是使用Qt样式表. Q ...

  8. Qt+ECharts开发笔记(二):Qt窗口动态调整大小,使ECharts跟随Qt窗口大小变换而变换大小

    前言   上一篇将ECharts嵌入Qt中,在开始ECharts使用之前,还有一个很重要的功能,就是在窗口变换大小的时候,ECharts的图表尺寸也要跟随Qt窗口变换大小而变换大小.   Demo演示 ...

  9. CentOS下Qt窗口透明效果失效,成黑色背景的问题

    一.问题 Linux系统下Qt窗口的透明效果成了黑色,但同样的代码在windows机子上有透明效果,主要是修改系统的配置,仅在centos6.3及其以上版本实验过.其他系统可以相应配置. 二.问题运行 ...

随机推荐

  1. bootstrap之noConflict的详解

    翻开推特框架,不经发现,几乎所有的插件都会出现noConflict的写法来防止和其他的插件冲突!我们以button.js为例子,打开其源代码发现 如下: var old = $.fn.button $ ...

  2. js数组的操作<转>

    转自 http://blog.csdn.net/xcxinghai/article/details/13502583 PS(个人理解): 1) 数组项的数据类型可以是混合多样的,同时可以含string ...

  3. codevs 1913 数字梯形问题 费用流

    题目链接 给你一个数字梯形, 最上面一层m个数字, 然后m+1,......m+n-1个. n是层数. 在每个位置, 可以向左下或右下走.然后让你从最顶端的m个数字开始, 走出m条路径, 使得路过的数 ...

  4. STM32与LPC系列ARM资源之比较

    由于有周立公开发板的影响,LPC系列的开发板在工程师心目中一般是入门的最好型号之一.这次刚好有STM32的竞赛,正好将两者的资源进行比较一下(LPC系列以LPC213X为例). LPC213X包括LP ...

  5. 去掉ILDasm的SuppressIldasmAttribute限制

    原文:去掉ILDasm的SuppressIldasmAttribute限制 今天本打算汉化一个.Net程序的,当用ILDasm打开的时候,出现了"受保护模块—无法进行反汇编"的错误 ...

  6. ASP 代码当前记录集不支持更新问题的解决办法。

    错误类型: ADODB.Recordset (0x800A0CB3) 当前记录集不支持更新.这可能是提供程序的限制,也可能是选定锁定类型的限制. /Model/manage/Admin_Admin.a ...

  7. 使用 Node.js 做 Function Test

    Info 上周 meeting 上同事说他们现在在用 java 写 function test,产生了很多冗余的代码,整个项目也变得比较臃肿.现在迫切需要个简单的模板项目能快速搭建function t ...

  8. yum localinstall rpm

  9. [置顶] 自娱自乐6之Linux gadget驱动5(自编gadget驱动,包涵与之通讯的主机usb驱动,已调试通过)

    这个代码调试,你首先要保证你的udc驱动没用问题,这个有些矛盾,应为我本来要用gadget驱动来调试udc驱动,结果反过来了. 这是在zero基础改的,大概的改动 1. 去掉loop. 2. sink ...

  10. float

    .clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: b ...