We draw widgets in the window title

    It's no secret to anyone, today the population is mainly dominated by widescreen monitors and they are forced to save the number of pixels vertically. This spawned a fashion for drawing controls right in the window title. Now you won’t surprise anyone with this, but, nevertheless, I haven’t found a solution to this problem on Qt, so now we will fix it:



    In the dark dungeons of our qutIM laboratorythe ToolFrameWindow class was born, which is very similar to classes such as QMainWindow and QToolBar. I won’t describe the WinAPI ordeals; I don’t want to clutter up the article. To achieve this effect, it is necessary to expand the client area to the entire window and manually handle the cursor position so that you can move and resize the window. At the same time, transparency disappears, for its return QtDWM helps us.

    Next, I would like to describe the principle of its use:


    First of all, you need to give him a widget for which we will draw the buttons in the header, this is done by calling the setCentralWidget method. This is done in such a way that it is as easy as possible to transfer existing code and not create difficulties on other platforms.

    ToolFrameWindow w;
    Form form;
    w.setCentralWidget(&form);

    * This source code was highlighted with Source Code Highlighter.





    Adding Actions:

    Buttons are added to the header using the addAction method, you can also add empty addSpace or add the addSeparator separator.

    QAction action(&w);
    w.addSpace(16);
    w.addAction(&action);
    w.addSeparator();

    * This source code was highlighted with Source Code Highlighter.



    Adding tabs, buttons, labels and other widgets:


    Especially for adding all this disgrace, the addWidget method was provided, when adding, you can specify the alignment through Qt :: Aligment, which allows you to make buttons like in the screenshot. As for the button itself, it is made of QPushButton using qss styles, in particular border-image helped a lot. I tried using QGraphicsDropShadowEffect to draw a glow under the text, but the strength of the glow turned out to be too small. This led to some confusion, but I remembered the good old border-image and decided to make a horse move: draw a glow as a picture and apply it as border-image

      QPushButton btn;
      btn.setIcon(QIcon(":/ubuntu.png"));
      btn.setStyleSheet("QPushButton { "
               "border: 5px;"
               "border-image: url(:/button.png);"
               "}");
      btn.setMinimumSize(64, 22);
      btn.setMaximumSize(64, 22);

    * This source code was highlighted with Source Code Highlighter.




      QLabel lbl(QObject::tr("Glow caption. Text with glow"));
      lbl.setStyleSheet("QLabel {border-image: url(:/background.png);border: 5px; }");

    * This source code was highlighted with Source Code Highlighter.


    It turned out not quite perfect, there is still much to strive for in choosing the right parameters and dimensions of the glow, but in general this solution is quite simple and at the same time flexible.

    I want to note that Qt sometimes tears the roof off because the widget's space has expanded due to the title. For example, pos () can now take negative values, although this should ideally not be.

    Conclusion


    One small screenshot:

    The most daring can try this plugin. But it has not yet been frankly completed, we will talk about it later.

    Many thanks to dtf for the war with APIs and for the implementation of all winAPI methods. The library code is available in gitorious (download the habrahabr tag). The license is currently GPLv2. To use it in your code, it is enough to copy the necessary files to your project, the test program is in the wincaption directory.

    Also popular now: