Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Memory leak using StyleSheet
Forum Updated to NodeBB v4.3 + New Features

Memory leak using StyleSheet

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 3 Posters 2.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    zonman
    wrote on last edited by zonman
    #4

    One more thing, I tried to add styles to qss file (for table they are style-properties starts with #, after comments)., but result is the same.

    darkstyle.h

    #ifndef DARKSTYLE_H
    #define DARKSTYLE_H
    
    #include <QApplication>
    #include <QFile>
    #include <QFont>
    #include <QPainter>
    #include <QProxyStyle>
    #include <QStyleFactory>
    #include <QWidget>
    
    class DarkStyle : public QProxyStyle
    {
        Q_OBJECT
    public:
        DarkStyle();
        explicit DarkStyle(QStyle *style);
        QStyle *baseStyle() const;
    
        void polish(QPalette &palette) override;
        void polish(QApplication *app) override;
    
    private:
        QStyle *styleBase(QStyle *style = nullptr) const;
    };
    
    #endif // DARKSTYLE_H
    

    darkstyle.cpp

    #include "darkstyle.h"
    
    DarkStyle::DarkStyle() : DarkStyle(styleBase()) {}
    
    DarkStyle::DarkStyle(QStyle *style) : QProxyStyle(style) {}
    
    QStyle *DarkStyle::styleBase(QStyle *style) const
    {
        static QStyle *base = !style ? QStyleFactory::create(QStringLiteral("Fusion")) : style;
        return base;
    }
    
    QStyle *DarkStyle::baseStyle() const { return styleBase(); }
    
    void DarkStyle::polish(QPalette &palette)
    {
        // modify palette to dark
        palette.setColor(QPalette::Window, QColor(53, 53, 53));
        palette.setColor(QPalette::WindowText, Qt::white);
        palette.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127));
        palette.setColor(QPalette::Base, QColor(42, 42, 42));
        palette.setColor(QPalette::AlternateBase, QColor(66, 66, 66));
        palette.setColor(QPalette::ToolTipBase, Qt::white);
        palette.setColor(QPalette::ToolTipText, QColor(53, 53, 53));
        palette.setColor(QPalette::Text, Qt::white);
        palette.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127));
        palette.setColor(QPalette::Dark, QColor(35, 35, 35));
        palette.setColor(QPalette::Shadow, QColor(20, 20, 20));
        palette.setColor(QPalette::Button, QColor(53, 53, 53));
        palette.setColor(QPalette::ButtonText, Qt::white);
        palette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127));
        palette.setColor(QPalette::BrightText, Qt::red);
        palette.setColor(QPalette::Link, QColor(42, 130, 218));
        palette.setColor(QPalette::Highlight, QColor(42, 130, 218));
        palette.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80, 80, 80));
        palette.setColor(QPalette::HighlightedText, Qt::white);
        palette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(127, 127, 127));
    }
    
    void DarkStyle::polish(QApplication *app)
    {
        if (!app)
            return;
    
        // increase font size for better reading,
        // setPointSize was reduced from +2 because when applied this way in Qt5, the
        // font is larger than intended for some reason
        QFont defaultFont = QApplication::font();
        defaultFont.setPointSize(defaultFont.pointSize());
        app->setFont(defaultFont);
    
        // loadstylesheet
        QFile qfDarkstyle(QStringLiteral(":/darkstyle/darkstyle.qss"));
        if (qfDarkstyle.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            // set stylesheet
            QString qsStylesheet = QString::fromLatin1(qfDarkstyle.readAll());
            app->setStyleSheet(qsStylesheet);
            qfDarkstyle.close();
        }
    }
    
    

    darkstyle.qss

    QScrollBar::handle:horizontal:hover{
      background-color:palette(highlight);
    }
    QScrollBar::add-line:horizontal{
      background:none;
      width:0px;
      subcontrol-position:bottom;
      subcontrol-origin:margin;
    }
    QScrollBar::sub-line:horizontal{
      background:none;
      width:0px;
      subcontrol-position:top;
      subcontrol-origin:margin;
    }
    QSlider::handle:horizontal{
      border-radius:4px;
      border:1px solid rgba(25,25,25,255);
      background-color:palette(alternate-base);
      min-height:20px;
      margin:0 -4px;
    }
    QSlider::handle:horizontal:hover{
      background:palette(highlight);
    }
    QSlider::add-page:horizontal{
      background:palette(base);
    }
    QSlider::sub-page:horizontal{
      background:palette(highlight);
    }
    QSlider::sub-page:horizontal:disabled{
      background:rgb(80,80,80);
    }
    
    /* EditDigitalSignalTable */
    
    /* Table cells */
    QLabel#EditTableCells{
      background-color:palette(base);
      border:1px solid palette(dark);
      border-top-style: none;
      border-left-style: none;
      padding-left:5px;
      padding-right:5px;
    }
    QPushButton#EditTableCells, QSpinBox#EditTableCells{
      background-color:palette(base);
    }
    /* Table headers */
    #EditTableHeaderTime, #EditTableHeaderDuration{
      background:rgb(60,60,60);
      border-top:1px solid palette(dark);
      border-bottom:1px solid palette(dark);
      padding-left:5px;
      padding-right:5px;
    }
    #EditTableHeaderState{
     background:rgb(60,60,60);
     border-top:1px solid palette(dark);
     border-right:1px solid palette(dark);
     border-bottom:1px solid palette(dark);
     padding-left:5px;
     padding-right:5px;
    }
    /* Table corner cell */
    #EditTableHeaderNumber{
     border:1px solid palette(dark);
     padding-left:5px;
     padding-right:5px;
     background:rgb(90,90,90);
    }
    QTableView QTableCornerButton::section{
      background:rgb(75,75,75);
    }
    /* Table vertical header */
    #EditTableCellNumber{
     background:rgb(60,60,60);
     border:1px solid palette(dark);
     border-top-style: none;
     padding-left:5px;
     padding-right:5px;
    }
    /* Tab-widget that contains edit-table*/
    #EditTabWidget{
       background:rgb(53,53,53);
    }
    
    1 Reply Last reply
    0
    • Axel SpoerlA Offline
      Axel SpoerlA Offline
      Axel Spoerl
      Moderators
      wrote on last edited by
      #5

      You don't have to re-implement the paint event.
      Just instead of using stylesheets I would use a standard style shipped with Qt.
      Depending on your operating system and window manager, a suitable default style will be chosen automatically.
      Instead of calling setStyleSheet() on your widget, you read its palette, set the respective brush and call widget->setPalette() again. A paint event will then be posted and your widget gets painted without a style sheet string having to be interpreted.
      Please read the documentation of QPalette, which I have linked in my previous post. Everything is explained there and you can also examine code examples.

      Software Engineer
      The Qt Company, Oslo

      Z 1 Reply Last reply
      0
      • Axel SpoerlA Axel Spoerl

        You don't have to re-implement the paint event.
        Just instead of using stylesheets I would use a standard style shipped with Qt.
        Depending on your operating system and window manager, a suitable default style will be chosen automatically.
        Instead of calling setStyleSheet() on your widget, you read its palette, set the respective brush and call widget->setPalette() again. A paint event will then be posted and your widget gets painted without a style sheet string having to be interpreted.
        Please read the documentation of QPalette, which I have linked in my previous post. Everything is explained there and you can also examine code examples.

        Z Offline
        Z Offline
        zonman
        wrote on last edited by
        #6

        @Axel-Spoerl, yes, but how can I create border to widget with QPalette? As I understood reading doc, it works mostly with color, using roles. And one more thing, how to control paint-border for specific sides(not all 4), when I have table?

        1 Reply Last reply
        0
        • Axel SpoerlA Offline
          Axel SpoerlA Offline
          Axel Spoerl
          Moderators
          wrote on last edited by
          #7

          The code manually implements parts of QTableView, respectively QTableWidget. These classes have an out-of-the-box implementation for column headers and row numbers, which your code creates labels for. They also provide a visual grid, which can probably substitute drawing borders around every widget. Such grids can be styled and they are rendered more efficiently: Instead of drawing a rectangle around each widget, they consist of vertical and horizontal lines across the entire viewport. They get repainted only if necessary (e.g. due to resizing or scroll moves below grid size). And as a bycatch, your users will be able to navigate cells with cursor keys - if you allow it to happen.

          In case you use QTableView, you can store your data in a QAbstractTableModel, define selection models, which gives you focus on data while leaving its visual representation (including drag & drop, sorting) to the system.

          QTableWidget has a simpler API at the cost of less flexibility in data management.

          Software Engineer
          The Qt Company, Oslo

          Z 1 Reply Last reply
          1
          • Axel SpoerlA Axel Spoerl

            The code manually implements parts of QTableView, respectively QTableWidget. These classes have an out-of-the-box implementation for column headers and row numbers, which your code creates labels for. They also provide a visual grid, which can probably substitute drawing borders around every widget. Such grids can be styled and they are rendered more efficiently: Instead of drawing a rectangle around each widget, they consist of vertical and horizontal lines across the entire viewport. They get repainted only if necessary (e.g. due to resizing or scroll moves below grid size). And as a bycatch, your users will be able to navigate cells with cursor keys - if you allow it to happen.

            In case you use QTableView, you can store your data in a QAbstractTableModel, define selection models, which gives you focus on data while leaving its visual representation (including drag & drop, sorting) to the system.

            QTableWidget has a simpler API at the cost of less flexibility in data management.

            Z Offline
            Z Offline
            zonman
            wrote on last edited by
            #8

            @Axel-Spoerl , Yes it does. But I have been working at this task for already 2 weeks and used: QTableWIdget(too much widgets and it doesnt work), QTableView + delegate (but delegates creates only after clicking on cells and it doesnt work immidiately, like QSpinBox and other widgets).
            That's why I did this table by my own . And main question: Is re-paint, using paintEvent, best variant or can I use other paint things?

            1 Reply Last reply
            0
            • Axel SpoerlA Offline
              Axel SpoerlA Offline
              Axel Spoerl
              Moderators
              wrote on last edited by Axel Spoerl
              #9

              Feel free to hate me - I am going to be blunt and honest: If heading to the wrong direction, change your way. Pushing, speeding and suspecting others won't get you anywhere. StyleSheets don't leak memory and QTableWidget rocks 30k items with no issue.

              I'd call 2 weeks of research an investment in finding out that the hard way is eating memory and CPU as a snack between breakfast and lunch.
              Read the documentation carefully and use the tools available for managing large matrices of widgets. If you struggle, this forum will help you.

              If you stick to your individual implementation, that's totally fine. A price is to be paid for parsing style sheet strings and/or drawing rectangles around each widget. It doesn't matter much, if it's done by generic paint events, or by an individual method that overrides QWidget::paintEvent. I trust you understand that we can't be of much help in how to implement QTableWidget without QTableWidget.

              Software Engineer
              The Qt Company, Oslo

              Z JoeCFDJ 2 Replies Last reply
              1
              • Axel SpoerlA Axel Spoerl

                Feel free to hate me - I am going to be blunt and honest: If heading to the wrong direction, change your way. Pushing, speeding and suspecting others won't get you anywhere. StyleSheets don't leak memory and QTableWidget rocks 30k items with no issue.

                I'd call 2 weeks of research an investment in finding out that the hard way is eating memory and CPU as a snack between breakfast and lunch.
                Read the documentation carefully and use the tools available for managing large matrices of widgets. If you struggle, this forum will help you.

                If you stick to your individual implementation, that's totally fine. A price is to be paid for parsing style sheet strings and/or drawing rectangles around each widget. It doesn't matter much, if it's done by generic paint events, or by an individual method that overrides QWidget::paintEvent. I trust you understand that we can't be of much help in how to implement QTableWidget without QTableWidget.

                Z Offline
                Z Offline
                zonman
                wrote on last edited by zonman
                #10

                @Axel-Spoerl No, thank you a lot for the help. I am new in Qt and learn all these stuff step by step. Okay, custom implementation will be the best, for my case, because QTableWidget is okay for less than 20'000 (if we have 3 buttons in row), after it it doesn't work. My project uses more than 100'000 points, so it is 3 * 100'000 widgets in general. But thank for your time.

                And main rule: NOT use customStyle for table with a lot of rows

                I've already written about it:
                https://forum.qt.io/topic/137658/table-with-large-amount-of-widgets-100-000

                1 Reply Last reply
                0
                • Axel SpoerlA Axel Spoerl

                  Feel free to hate me - I am going to be blunt and honest: If heading to the wrong direction, change your way. Pushing, speeding and suspecting others won't get you anywhere. StyleSheets don't leak memory and QTableWidget rocks 30k items with no issue.

                  I'd call 2 weeks of research an investment in finding out that the hard way is eating memory and CPU as a snack between breakfast and lunch.
                  Read the documentation carefully and use the tools available for managing large matrices of widgets. If you struggle, this forum will help you.

                  If you stick to your individual implementation, that's totally fine. A price is to be paid for parsing style sheet strings and/or drawing rectangles around each widget. It doesn't matter much, if it's done by generic paint events, or by an individual method that overrides QWidget::paintEvent. I trust you understand that we can't be of much help in how to implement QTableWidget without QTableWidget.

                  JoeCFDJ Offline
                  JoeCFDJ Offline
                  JoeCFD
                  wrote on last edited by JoeCFD
                  #11

                  @Axel-Spoerl Just curious: you really create 30k items while they can not be displayed at the same time? Is there a way to display only some of them on demand while the data is stored in the model or somewhere? I will never want to create so many items in a table at the same time.

                  Axel SpoerlA 1 Reply Last reply
                  0
                  • JoeCFDJ JoeCFD

                    @Axel-Spoerl Just curious: you really create 30k items while they can not be displayed at the same time? Is there a way to display only some of them on demand while the data is stored in the model or somewhere? I will never want to create so many items in a table at the same time.

                    Axel SpoerlA Offline
                    Axel SpoerlA Offline
                    Axel Spoerl
                    Moderators
                    wrote on last edited by
                    #12

                    @JoeCFD It would be possible, however, not the most elegant way. QTableView offers rich possibilities to store data in a model and render only what is needed. That's what I would use for large data volumes.

                    Software Engineer
                    The Qt Company, Oslo

                    JoeCFDJ 1 Reply Last reply
                    2
                    • Axel SpoerlA Axel Spoerl

                      @JoeCFD It would be possible, however, not the most elegant way. QTableView offers rich possibilities to store data in a model and render only what is needed. That's what I would use for large data volumes.

                      JoeCFDJ Offline
                      JoeCFDJ Offline
                      JoeCFD
                      wrote on last edited by JoeCFD
                      #13

                      @Axel-Spoerl Got it. Thanks. I may have a peek into the source code and see how it is done.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved