Qt窗口的标题栏自绘
因个人需要,要修改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:

#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窗口的标题栏自绘的更多相关文章
- Qt编程—去掉标题栏和设置窗口透明用法
学习Qt编程,有时候我们很想做出好看又比较炫的画面,这时就常用到qt上的一些技巧. 这里我以一个小例子来展示qt的这些技巧,此qt编程写的,如图:(去掉标题栏和设置窗口透明后) 代码实现部分: .h文 ...
- Qt之去除窗口的标题栏、通过鼠标移动窗口
设置标题栏图标,位置与大小示例 #include<QApplication> #include<QWidget> #include<QDebug> #include ...
- 调色板类QPalette——包含了Qt窗口不见的颜色组(collor group),和Windows右键属性外观非常类似
QPalette类包含了Qt窗口不见的颜色组(collor group); 1.Active组,该组的颜色用户当前活动的(active)窗口,即具有键盘或鼠标焦点的窗口; 2.Inactive组,该组 ...
- Qt窗口定制
qt中的QWidget窗口支持窗体绘制,但是不支持窗口标题栏绘制,想要美观的界面,还需要自己去定制,下面我就介绍一种定制窗体的方法 一个窗口无非就3部分,标题栏.窗体和状态栏,接下来我定制的窗口没有状 ...
- QT 窗口拖拽移动实现
我们知道,要实现窗口移动可以直接鼠标点住窗口的标题栏实现拖拽移动,这是窗口默认的行为,在QT中的事件响应函数为moveEvent. 但是现实中经常需要鼠标点住窗口客户区域实现窗口的拖拽移动,代码实现如 ...
- [DForm]我也来做自定义Winform之另类标题栏重绘
据说得有楔子 按照惯例,先来几张样例图(注:为了展示窗口阴影效果,截图范围向外扩展了些,各位凭想象吧). 还要来个序 其实,很多年没写过Winform了,前端时间在 ...
- 自定义QT窗口部件外观之QStyle
自定义QT窗口部件外观 重新定义Qt内置窗口部件的外观常用的方法有两种:一是通过子类化QStyle 类或者预定义的一个样式,例如QWindowStyle,来定制应用程序的观感:二是使用Qt样式表. Q ...
- Qt+ECharts开发笔记(二):Qt窗口动态调整大小,使ECharts跟随Qt窗口大小变换而变换大小
前言 上一篇将ECharts嵌入Qt中,在开始ECharts使用之前,还有一个很重要的功能,就是在窗口变换大小的时候,ECharts的图表尺寸也要跟随Qt窗口变换大小而变换大小. Demo演示 ...
- CentOS下Qt窗口透明效果失效,成黑色背景的问题
一.问题 Linux系统下Qt窗口的透明效果成了黑色,但同样的代码在windows机子上有透明效果,主要是修改系统的配置,仅在centos6.3及其以上版本实验过.其他系统可以相应配置. 二.问题运行 ...
随机推荐
- codeforces 几道题目
BZOJ挂了....明天就要出发去GDKOI了....不能弃疗. 于是在cf水了几道题, 写写详(jian)细(dan)题解, 攒攒RP, 希望GDKOI能好好发挥....... 620E. New ...
- Android.Hack.02_Animations
#01# TextView 和 ImageView TextView和Imageview切换卡顿,为了实现更好的切换,可以用动画来实现,系统自带的TextViewSwitcher 和ImageView ...
- 【学习笔记03】Javascript数组学习
数组定义的方法一: var Myarr=new Array(); //先声明一维 for(var i=0;i<2;i++){ //一维长度2 Myarr[i]=new Array(); //再声 ...
- thinkphp批量删除的实现
今天自己在写后台的时候需要把以前上传的测试文章全部删除掉,但是利用 [操作]里面的一个个删除比较慢,因此想出一个批量删除的解决方案. 首先在前端页面里面建立一个表单,这个表单是把你选中的单选按钮提交到 ...
- Java之线程的生命周期
在Java中,线程有5中不同状态,分别是:新建(New).就绪(Runable).运行(Running).阻塞(Blocked)和死亡(Dead).它们之间的转换图如下: 上图有一个例外,调用yiel ...
- jquery.post方法回调函数
1 function(data){} 此post请求成功后调用之,data是请求成功后服务器返回的东西.如果在servlet中有response.getWriter().println("s ...
- 常用在线工具及API网址总结
1.小图标在线查找 https://www.iconfinder.com/ 2.在线做图,Flowchart流程图,BPMN图,Org组织结构图等 http://www.processon.com/ ...
- java.lang.OutOfMemoryError: PermGen space 解决方案
只需两步: 将值改为512或者1024,然后CTRL+S,重启tomcat 和eclipse即可.
- c++策略模式
这几天需要学习一下设计模式来为设计代码结构使得代码可扩展性强,代码更加易于维护,不用想很长时间也不知道怎么去设计一个工具的代码. 我的理解策略模式: 1.有一个策略基类,策略类是什么呢?策略类就是一个 ...
- LDT自己定义启动模拟器
近期使用LUA开发手游,团队里大神自研了个框架,底层C++渲染,上层LUA处理逻辑. LUA的IDE选择LDT,不爽的是它不能自己主动启动模拟器,看过COCOSIDE能自启动,于是我想改造下LDT让它 ...