Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2707522
  • 博文数量: 416
  • 博客积分: 10220
  • 博客等级: 上将
  • 技术积分: 4193
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-15 09:47
文章分类

全部博文(416)

文章存档

2022年(1)

2021年(1)

2020年(1)

2019年(5)

2018年(7)

2017年(6)

2016年(7)

2015年(11)

2014年(1)

2012年(5)

2011年(7)

2010年(35)

2009年(64)

2008年(48)

2007年(177)

2006年(40)

我的朋友

分类: C/C++

2009-05-17 11:13:48

 
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.


#include    
#include    
#include    
#include
class ImTitleBar : public QWidget   
{  
 Q_OBJECT
public:
 ImTitleBar(QWidget *parent)
  :QWidget(parent)
 {   
 }
protected:
 void paintEvent(QPaintEvent *)
 {
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
 }
};
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) ; 
  //setPalette(QPalette(QColor(250, 0, 0)));
  minimize = new QToolButton(this) ; 
  maximize = new QToolButton(this) ; 
  close= new QToolButton(this) ; 
  setFixedHeight(35);
  // Use the style to set the button pixmaps   
  QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton) ; 
  close->setIcon(pix) ;
  close->setObjectName("Close");
  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->setObjectName("title");
  label->setText("Window Label") ; 
  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) ; 
 }
protected:
 void paintEvent(QPaintEvent *)
 {
  QStyleOption opt;
  opt.init(this);
  QPainter p(this);
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
 }
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)        
 {   
  Q_UNUSED(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) ; 
 l->addWidget(new QPushButton("Start")) ; 
 ImTitleBar *line = new ImTitleBar(NULL);
 //QWidget *line = new QWidget;
 //line->setPalette(QPalette(QColor(250, 250, 0)));
 line->setObjectName("Line");
 //line->setWindowTitle("Line Title");
 line->setAutoFillBackground(true);
 line->setBackgroundRole(QPalette::Highlight) ; 
 //line->setPalette(QPalette(QColor(250, 250, 0)));
 line->setFixedHeight(25);
 QLabel *label = new QLabel(line) ; 
 label->setText("Window Label") ;
 l->addWidget(line) ; 
 box.show() ;  
 //QLabel{ background-color: blue; color: red;}
 QString sStyle = "QPushButton{ background-color:red; }\
      TitleBar { background: #FF6699; color: red; background-image: url(:/images/woodbackground.png);}\
      TitleBar#title { color: red;}\
      TitleBar::title { color: red;}\
      TitleBar QLabel { color: red;}\
      Line { background: green;}\
      ImTitleBar { background: green;}\
      TitleBar QToolButton#Close{ background-color:red; }";
 app.setStyleSheet(sStyle);
 return app.exec() ; 
}

Note that some strange behavior may be seen when resizing the window really small horizonally to the right on Windows (the window will start moving instead of resizing). This is due to limitations on Windows and there is nothing we can do about this unfortunately.


#include    
#include    
#include    
#include
class ImTitleBar : public QWidget   
{  
 Q_OBJECT
public:
 ImTitleBar(QWidget *parent)  :QWidget(parent)
 {   
  frame = new QFrame(this);
  frame->resize(size());
  frame->setObjectName("TitleBar");
 }
protected:
 void paintEvent(QPaintEvent *)
 {
  frame->resize(size());
  QStyleOption opt;  
  opt.init(this);  
  QPainter p(this);  
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
 }
private:
 QFrame *frame;
};
class TitleBar : public QWidget   
{  
 Q_OBJECT
public: 
 TitleBar(QWidget *parent)
 {
  frame = new QFrame(this);
  frame->resize(size());
  frame->setObjectName("TitleBarBg");
  // 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) ;  
  //setPalette(QPalette(QColor(250, 0, 0)));  
  minimize = new QToolButton(this) ;  
  maximize = new QToolButton(this) ;  
  close= new QToolButton(this) ;  
  setFixedHeight(35);  
  // Use the style to set the button pixmaps
  QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton) ;  
  close->setIcon(pix) ;  
  close->setObjectName("Close");  
  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->setObjectName("title");  
  label->setText("Window Label") ;  
  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) ;  
 }
protected:
 void paintEvent(QPaintEvent *)
 {
  frame->resize(size());
  QStyleOption opt;  
  opt.init(this);  
  QPainter p(this);  
  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
 }
private:
 QFrame *frame;
 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)
 {
  Q_UNUSED(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)   

 Q_INIT_RESOURCE(styles);
 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) ;  
 l->addWidget(new QPushButton("Start")) ;  
 ImTitleBar *line = new ImTitleBar(NULL);
 //QWidget *line = new QWidget;
 //line->setPalette(QPalette(QColor(250, 250, 0)));
 line->setObjectName("Line");
 //line->setWindowTitle("Line Title");
 line->setAutoFillBackground(true);
 line->setBackgroundRole(QPalette::Highlight) ;  
 //line->setPalette(QPalette(QColor(250, 250, 0)));
 line->setFixedHeight(105);
 QLabel *label = new QLabel(line) ;  
 label->setText("Window Label") ;
 l->addWidget(line) ;  
 box.show() ;  
 QString sStyle ="QPushButton{ background-color:red; } \
     TitleBar { color: red; } \
     TitleBar#title  { color: red;}\
     TitleBar::title { color: red;}\
     TitleBar QLabel { color: red;}\
     QFrame#titleFrame {border: 20; border-image: url(:/images/titlebar_c.png) 20 20 20 20;}\
     ImTitleBar QFrame#TitleBar {background: red;border-width: 30 30 5 30; border-image: url(:/images/titlebar_c.png) 30 30 5 30;}\
     TitleBar QFrame#TitleBarBg {background: white;border-width: 30 30 5 30; border-image: url(:/images/titlebar_c.png) 30 30 5 30;}\
     TitleBar QToolButton#Close{ background-color:red; }";
 app.setStyleSheet(sStyle);
 return app.exec() ;  
}

附:图片及效果图
阅读(1714) | 评论(3) | 转发(0) |
0

上一篇:QDialog::QDialog style

下一篇:QT titleBar

给主人留下些什么吧!~~

chinaunix网友2009-07-21 22:15:19

暂时把所有的image放到styles.rc文件中,要在pro文件中引用,生成vc工程时才能加载上,主要看VC工程资源有是否有styles.rc文件

chinaunix网友2009-07-17 17:52:30

我的QQ号是:289303723,邮箱:diaopan1985@163.com QT新手,有很多问题希望能请教你一下。

chinaunix网友2009-07-17 17:49:30

你好,编译代码时出现error LNK2019: unresolved external symbol "int __cdecl qInitResources_styles(void)" (?qInitResources_styles@@YAHXZ) referenced in function _main。请问是什么原因啊?