- All (478)
- jom (0)
- Qt Linguist (7)
- Qt Eclipse Integration (9)
- Qt Designer (7)
- Qt Creator (4)
- Qt build system: qmake (31)
- Qt build system: configure (3)
- Qt Assistant (5)
- Printing (4)
- Porting from Qt 3 to Qt 4 (1)
- Plugins (7)
- Qt Visual Studio AddIn (2)
- Qt/MFC Migration (2)
- QtScript (3)
- MDI (2)
- XML (1)
- Widgets (22)
- WebKit (5)
- Tools and Containers (2)
- Threads (2)
- Text Handling (10)
- SQL (6)
- QtTest (1)
- QtService (1)
- Platform: Windows (49)
- Platform: Unix (16)
- Platform: Mac OS X (18)
- Image Formats (2)
- I/O (2)
- Graphicsview (8)
- Font handling (9)
- Event System (18)
- Drag and Drop (4)
- Dialogs (6)
- Desktop integration (3)
- ActiveQt (3)
- Itemviews (60)
- Layout (4)
- Qt Quick (10)
- Qt SDK (1)
- Licensing (2)
- Platform: Embedded Linux (38)
- Painting (32)
- OpenGL (4)
- Object Model (6)
- Network (5)
- Multimedia (3)
- Miscellanous (23)
- Main Window (19)
- Look and Feel (23)
- Development (0)
- Getting Involved (0)
- Routines (0)
How can I handle events in the titlebar and change its color etc ?
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 [doc.qt.nokia.com] 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 [doc.qt.nokia.com] subclass which does not have a titlebar provided via the window system. This is done by setting the Qt::FramelessWindowHint [doc.qt.nokia.com] 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 <QtGui>
- {
- Q_OBJECT
- public:
- {
- // 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
- // Use the style to set the button pixmaps
- close->setIcon(pix);
- maximize->setIcon(maxPix);
- minimize->setIcon(pix);
- minimize->setMinimumHeight(20);
- close->setMinimumHeight(20);
- maximize->setMinimumHeight(20);
- label->setText("Window Title");
- parent->setWindowTitle("Window Title");
- hbox->addWidget(label);
- hbox->addWidget(minimize);
- hbox->addWidget(maximize);
- hbox->addWidget(close);
- hbox->insertStretch(1, 500);
- hbox->setSpacing(0);
- 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:
- {
- startPos = me->globalPos();
- clickPos = mapToParent(me->pos());
- }
- {
- if (maxNormal)
- return;
- parentWidget()->move(me->globalPos() - clickPos);
- }
- private:
- bool maxNormal;
- QPoint startPos;
- QPoint clickPos;
- };
- {
- public:
- Frame()
- {
- m_mouse_down = false;
- setFrameShape(Panel);
- // Make this a borderless window which can't
- // be resized or moved via the window system
- setMouseTracking(true);
- m_titleBar = new TitleBar(this);
- vbox->addWidget(m_titleBar);
- vbox->setMargin(0);
- vbox->setSpacing(0);
- 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
- TitleBar *titleBar() const { return m_titleBar; }
- {
- m_old_pos = e->pos();
- }
- {
- 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();
- if (left)
- g.setLeft(g.left() + dx);
- if (right)
- g.setRight(g.right() + dx);
- if (bottom)
- g.setBottom(g.bottom() + dy);
- setGeometry(g);
- } else {
- 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)
- else
- } else if (hor) {
- } else if (bottom) {
- } else {
- }
- }
- }
- {
- m_mouse_down = false;
- }
- private:
- TitleBar *m_titleBar;
- QPoint m_old_pos;
- bool m_mouse_down;
- bool left, right, bottom;
- };
- #include "main.moc"
- int main(int argc, char **argv)
- {
- Frame box;
- box.move(0,0);
- l->setMargin(0);
- l->addWidget(edit);
- box.show();
- 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.

4 comments
January 10, 2011
Lab Rat
Nice !
But what happen if one add it into a QMdiArea and click on minimize ?
I think the window disappear …
May 19, 2011
Lab Rat
Possibly. This is just an example that is meant to give some tips on how you can create a custom titlebar in general. You need to tweak it to your specific use case, in order to get the behavior that is needed for you though.
April 10, 2012
Lab Rat
Thanks for the example, that was very useful.
But now i have a small problem:
When I press down a button in the titlebar and move the mouse the entire frame moves also. I tried the following code in the “mousePressEvent(QMouseEvent *me)” method:
if(ui->pushButtonClose->isDown()||ui->pushButtonMinimize->isDown()){ return;
}
parentWidget()->move(me->globalPos()-clickPos);
But that dowsn’t work. The method can’t access to the “ui->pushButtonClose->isDown()”.
How can that be achieved?
Best regards
September 6, 2012
Ant Farmer
In TitleBar class change this functions: