Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1759564
  • 博文数量: 198
  • 博客积分: 4088
  • 博客等级: 上校
  • 技术积分: 2391
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-15 16:29
个人简介

游戏开发,系统架构; 博客迁移到:http://www.jianshu.com/u/3ac0504b3b8c

文章分类

全部博文(198)

文章存档

2017年(1)

2016年(12)

2015年(1)

2014年(3)

2013年(13)

2012年(18)

2011年(150)

分类: C/C++

2011-07-22 10:01:27

Q:
     How can I handle events in the titlebar and change its color etc ?
A:
    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子类需要重载一些鼠标事件以控制窗口的缩放与移动.
  1. #include

  2. class TitleBar : public QWidget
  3. {
  4.     Q_OBJECT
  5. public:
  6.     TitleBar(QWidget *parent)
  7.     {
  8.         // Don't let this widget inherit the parent's backround color
  9.         setAutoFillBackground(true);
  10.         // Use a brush with a Highlight color role to render the background
  11.         setBackgroundRole(QPalette::Highlight);
  12.          
  13.         minimize = new QToolButton(this);
  14.         maximize = new QToolButton(this);
  15.         close= new QToolButton(this);
  16.          
  17.         // Use the style to set the button pixmaps
  18.         QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
  19.         close->setIcon(pix);
  20.          
  21.         maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton);
  22.         maximize->setIcon(maxPix);
  23.          
  24.         pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton);
  25.         minimize->setIcon(pix);

  26.         restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton);
  27.          
  28.         minimize->setMinimumHeight(20);
  29.         close->setMinimumHeight(20);
  30.         maximize->setMinimumHeight(20);
  31.          
  32.          
  33.         QLabel *label = new QLabel(this);
  34.         label->setText("Window Title");
  35.         parent->setWindowTitle("Window Title");
  36.          
  37.         QHBoxLayout *hbox = new QHBoxLayout(this);
  38.          
  39.         hbox->addWidget(label);
  40.         hbox->addWidget(minimize);
  41.         hbox->addWidget(maximize);
  42.         hbox->addWidget(close);
  43.          
  44.         hbox->insertStretch(1, 500);
  45.         hbox->setSpacing(0);
  46.         setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
  47.          
  48.         maxNormal = false;
  49.          
  50.         connect(close, SIGNAL( clicked() ), parent, SLOT(close() ) );
  51.         connect(minimize, SIGNAL( clicked() ), this, SLOT(showSmall() ) );
  52.         connect(maximize, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) );
  53.     }
  54.      
  55. public slots:
  56.     void showSmall()
  57.     {
  58.         parentWidget()->showMinimized();
  59.     }
  60.      
  61.     void showMaxRestore()
  62.     {
  63.         if (maxNormal) {
  64.             parentWidget()->showNormal();
  65.             maxNormal = !maxNormal;
  66.             maximize->setIcon(maxPix);
  67.         } else {
  68.             parentWidget()->showMaximized();
  69.             maxNormal = !maxNormal;
  70.             maximize->setIcon(restorePix);
  71.         }
  72.     }
  73. protected:
  74.     void mousePressEvent(QMouseEvent *me)
  75.     {
  76.         startPos = me->globalPos();
  77.         clickPos = mapToParent(me->pos());
  78.     }
  79.     void mouseMoveEvent(QMouseEvent *me)
  80.     {
  81.         if (maxNormal)
  82.             return;
  83.         parentWidget()->move(me->globalPos() - clickPos);
  84.     }

  85. private:
  86.     QToolButton *minimize;
  87.     QToolButton *maximize;
  88.     QToolButton *close;
  89.     QPixmap restorePix, maxPix;
  90.     bool maxNormal;
  91.     QPoint startPos;
  92.     QPoint clickPos;
  93. };

  94. class Frame : public QFrame
  95. {
  96. public:
  97.      
  98.     Frame()
  99.     {
  100.         m_mouse_down = false;
  101.         setFrameShape(Panel);
  102.          
  103.         // Make this a borderless window which can't
  104.         // be resized or moved via the window system
  105.         setWindowFlags(Qt::FramelessWindowHint);
  106.         setMouseTracking(true);
  107.          
  108.         m_titleBar = new TitleBar(this);
  109.          
  110.         m_content = new QWidget(this);
  111.          
  112.         QVBoxLayout *vbox = new QVBoxLayout(this);
  113.         vbox->addWidget(m_titleBar);
  114.         vbox->setMargin(0);
  115.         vbox->setSpacing(0);
  116.          
  117.         QVBoxLayout *layout = new QVBoxLayout(this);
  118.         layout->addWidget(m_content);
  119.         layout->setMargin(5);
  120.         layout->setSpacing(0);
  121.         vbox->addLayout(layout);
  122.     }
  123.      
  124.     // Allows you to access the content area of the frame
  125.     // where widgets and layouts can be added
  126.     QWidget *contentWidget() const { return m_content; }
  127.      
  128.     TitleBar *titleBar() const { return m_titleBar; }
  129.      
  130.     void mousePressEvent(QMouseEvent *e)
  131.     {
  132.         m_old_pos = e->pos();
  133.         m_mouse_down = e->button() == Qt::LeftButton;
  134.     }
  135.      
  136.     void mouseMoveEvent(QMouseEvent *e)
  137.     {
  138.         int x = e->x();
  139.         int y = e->y();
  140.          
  141.         if (m_mouse_down) {
  142.             int dx = x - m_old_pos.x();
  143.             int dy = y - m_old_pos.y();
  144.             
  145.             QRect g = geometry();
  146.             
  147.             if (left)
  148.                 g.setLeft(g.left() + dx);
  149.             if (right)
  150.                 g.setRight(g.right() + dx);
  151.             if (bottom)
  152.                 g.setBottom(g.bottom() + dy);
  153.             
  154.             setGeometry(g);
  155.             
  156.             m_old_pos = QPoint(!left ? e->x() : m_old_pos.x(), e->y());
  157.         } else {
  158.             QRect r = rect();
  159.             left = qAbs(x - r.left()) <= 5;
  160.             right = qAbs(x - r.right()) <= 5;
  161.             bottom = qAbs(y - r.bottom()) <= 5;
  162.             bool hor = left | right;
  163.             
  164.             if (hor && bottom) {
  165.                 if (left)
  166.                     setCursor(Qt::SizeBDiagCursor);
  167.                 else
  168.                     setCursor(Qt::SizeFDiagCursor);
  169.             } else if (hor) {
  170.                 setCursor(Qt::SizeHorCursor);
  171.             } else if (bottom) {
  172.                 setCursor(Qt::SizeVerCursor);
  173.             } else {
  174.                 setCursor(Qt::ArrowCursor);
  175.             }
  176.         }
  177.     }
  178.      
  179.     void mouseReleaseEvent(QMouseEvent *e)
  180.     {
  181.         m_mouse_down = false;
  182.     }
  183.      
  184. private:
  185.     TitleBar *m_titleBar;
  186.     QWidget *m_content;
  187.     QPoint m_old_pos;
  188.     bool m_mouse_down;
  189.     bool left, right, bottom;
  190. };


  191. #include "main.moc"

  192. int main(int argc, char **argv)
  193. {
  194.     QApplication app(argc, argv);
  195.      
  196.     Frame box;
  197.     box.move(0,0);
  198.      
  199.     QVBoxLayout *l = new QVBoxLayout(box.contentWidget());
  200.     l->setMargin(0);
  201.     QTextEdit *edit = new QTextEdit(box.contentWidget());
  202.     l->addWidget(edit);
  203.      
  204.     box.show();
  205.     return app.exec();   
  206. }
原文地址:How can I handle events in the titlebar and change its color etc ?
阅读(3642) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~