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. How can I replce Qpainter::drawText with a more effecient way to draw text in a table cell

How can I replce Qpainter::drawText with a more effecient way to draw text in a table cell

Scheduled Pinned Locked Moved Unsolved General and Desktop
19 Posts 6 Posters 1.8k Views
  • 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.
  • X Offline
    X Offline
    xce1
    wrote on last edited by xce1
    #1

    UPDATE:
    After tested with a simpler QWidget subclass, I realized may be it's not a drawText problem.
    I've removed the colorful gifs, but keep the last two gray or white gifs to better demonstrate the problem.

    the original post:
    I try to implement a simple table drawing widget by overriding the QWidget:PaintEvent method.
    Now I find that, before the text and color shows up, the window is about 1 second visible blank.
    This is the gif that shows the blank.
    Using VS2019 Perfomance Profiling Tools, We can see drawText occupies about 30% ~ 50% cpu work. And if I removed all the text
    drawing, the visible blank disappears.
    cb8f3cc3-f9e4-4359-aa38-6d11d5b32433-图片.png

    Here is my code.
    main.cpp

    #include <QtWidgets/QApplication>
    #include "QPlainStyleTable.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        auto _m_pTable = new QPlainStyleTable();
        _m_pTable->SetHeaderColor(Qt::red, Qt::green);
        _m_pTable->SetContentColor(Qt::gray, Qt::yellow, Qt::blue);
        _m_pTable->SetBorderColor(Qt::white);
        _m_pTable->SetFont(QFont("微软雅黑"), QFont("微软雅黑"));
    
        _m_pTable->SetDimension(8, 6);
    
        _m_pTable->SetTitle({ "姓名", "年龄", "性别", "学历", "籍贯" });
        _m_pTable->AddData({ "小红", "28", "女", "大学", "山东" });
        _m_pTable->AddData({ "姓名", "年龄", "性别", "学历", "籍贯" });
        _m_pTable->AddData({ "姓名", "年龄", "性别", "学历", "籍贯" });
        _m_pTable->AddData({ "姓名", "年龄", "性别", "学历", "籍贯" });
        _m_pTable->show();
        return a.exec();
    }
    
    

    QPlainStyleTable.h

    #pragma once
    
    #include <vector>
    #include <string>
    #include <functional>
    #include <map>
    #include <memory>
    
    #include <QWidget>
    #include <QPixmap>
    #include <QColor>
    #include <QFont>
    #include <QMenu>
    
    //返回true即不再可编辑
    using CellEditCallBack = std::function<void(int mouseX, int mouseY)>;
    
    class QPlainStyleTable : public QWidget
    {
        Q_OBJECT
    
    public:
        QPlainStyleTable(QWidget *parent = nullptr);
        ~QPlainStyleTable();
    
        void SetHeaderColor(const QColor& bkColor, const QColor& txtColor);
        void SetContentColor(const QColor& evenBkColor, const QColor& oddBkColor, const QColor& txtColor);
        void SetBorderColor(const QColor& color);
        void SetFont(const QFont& headerFont, const QFont& contentFont);
        void SetDimension(int row, int col);
    
        void SetTitle(const std::vector<std::string>& title);
        void AddData(const std::vector<std::string>& row);
        void ClearContent();
    
        void SetCellEditCallBack(int row, int col, CellEditCallBack callback);
        void SetUnEditable(int row, int col);
        void UpdateContent(int row, int col, const std::string& content);
    protected:
        virtual void paintEvent(QPaintEvent *event) override;
        virtual bool eventFilter(QObject *watched, QEvent *event) override;
    private:
        //缓存背景
        QPixmap bkCache;
        void DrawBk();
        bool BkSizeIsSame();
    
        //行列
        int row;
        int col;
    
        //单元格大小, 在画背景时计算出
        int headerH;
        int tailW;
        int cellH;
        int cellW;
    
        QColor headerBkColor;
        QColor headerTxtColor;
    
        QColor contentTxtColor;
        QColor evenBkColor;
        QColor oddBkColor;
        QColor borderColor;
    
        QFont headerFont;
        QFont contentFont;
    
        // headerText
        std::vector<std::string> title;
    
        // contentText
        std::vector<std::vector<std::string>> contents;
    
        struct EditableCell
        {
            int row;
            int col;
            bool operator<(const EditableCell& rhs) const
            {
                if (row == rhs.row)
                {
                    return col < rhs.col;
                }
                else if (col == rhs.col)
                {
                    return row < rhs.row;
                }
    
                return false;
            }
        };
    
        std::map<EditableCell, CellEditCallBack> callbacks;
        CellEditCallBack IsEditable(int row, int col);
    };
    
    

    QPlainStyleTable.cpp

    
    #include <algorithm>
    
    #include <QEvent>
    #include <QMouseEvent>
    #include <QPainter>
    #include "QPlainStyleTable.h"
    
    
    QPlainStyleTable::QPlainStyleTable(QWidget *parent)
        : QWidget(parent), row(0), col(0), cellW(0), cellH(0)
    {
        installEventFilter(this);
    }
    
    QPlainStyleTable::~QPlainStyleTable()
    {
    
    }
    
    void QPlainStyleTable::SetHeaderColor(const QColor& bkColor, const QColor& txtColor)
    {
        headerBkColor = bkColor;
        headerTxtColor = txtColor;
    }
    
    void QPlainStyleTable::SetContentColor(const QColor& evenBkColor, const QColor& oddBkColor, const QColor& txtColor)
    {
        this->evenBkColor = evenBkColor;
        this->oddBkColor = oddBkColor;
    
        this->contentTxtColor = txtColor;
    }
    
    void QPlainStyleTable::SetBorderColor(const QColor& color)
    {
        this->borderColor = color;
    }
    
    void QPlainStyleTable::SetFont(const QFont& headerFont, const QFont& contentFont)
    {
        this->headerFont = headerFont;
        this->contentFont = contentFont;
    }
    
    void QPlainStyleTable::SetDimension(int row, int col)
    {
        this->row = row;
        this->col = col;
    }
    
    void QPlainStyleTable::SetTitle(const std::vector<std::string>& title)
    {
        this->title = title;
    }
    
    void QPlainStyleTable::AddData(const std::vector<std::string>& row)
    {
        this->contents.push_back(row);
        update();
    }
    
    void QPlainStyleTable::ClearContent()
    {
        this->contents.clear();
        this->callbacks.clear();
        update();
    }
    
    void QPlainStyleTable::SetCellEditCallBack(int row, int col, CellEditCallBack callback)
    {
         callbacks[EditableCell{ row, col}] = callback;
    }
    
    void QPlainStyleTable::paintEvent(QPaintEvent *event)
    {
        if (bkCache.isNull())
        {
            DrawBk();
        }
        else
        {
            if (!BkSizeIsSame())
            {
                DrawBk();
            }
        }
    
        QPainter painter(this);
        painter.drawPixmap(rect(), bkCache);
    
        // DrawContentTxt
        painter.setFont(contentFont);
        painter.setPen(contentTxtColor);
        auto showRows = std::min((int)contents.size(), row);
        for (int idx = 0; idx < showRows; ++idx)
        {
            auto& oneRow = contents[idx];
            auto showCols = std::min((int)oneRow.size(), col);
            for (int idy = 0; idy < showCols; ++idy)
            {
                auto& txt = oneRow[idy];
                //painter.setPen(contentTxtColor);
                painter.setClipping(true);
                painter.drawText(idy * cellW, idx* cellH + headerH, cellW, cellH,
                    Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap
                    , QString::fromLocal8Bit(txt.c_str()));
    
                if (IsEditable(idx, idy))
                {
                    painter.setPen(Qt::red);
                    painter.setRenderHint(QPainter::Antialiasing);
                    painter.drawRoundedRect(idy * cellW, idx * cellH + headerH, cellW, cellH
                        , 2, 2);
                }
            }
        }
    }
    
    bool QPlainStyleTable::eventFilter(QObject *watched, QEvent *event)
    {
        if (watched == this
            && event->type() == QEvent::MouseButtonDblClick)
        {
            auto theEvent = (QMouseEvent*)event;
            auto x = theEvent->x();
            auto y = theEvent->y();
    
            auto clickRow = y < headerH ? -1 : (y - headerH) / cellH;
            auto clickCol = x / cellW;
            auto callback = IsEditable(clickRow, clickCol);
            if (callback)
            {
                auto globalPos = theEvent->globalPos();
                callback(globalPos.x(), globalPos.y());
            }
    
            return true;
        }
    
        return QWidget::eventFilter(watched, event);
    }
    
    void QPlainStyleTable::DrawBk()
    {
        QPixmap bk(width(), height());
    
        auto thisW = bk.width();
        auto thisH = bk.height();
        cellH = thisH / (row + 1);
        cellW = thisW / col;
        headerH = thisH - (cellH * row);
        tailW = thisW - (cellW * col);
    
        QPainter painter(&bk);
        painter.setPen(Qt::NoPen);
    
        // header
        painter.setBrush(headerBkColor);
        painter.drawRect(0, 0, thisW - 1, headerH - 1);
    
        headerFont.setHintingPreference(QFont::PreferNoHinting);
        painter.setFont(headerFont);
        painter.setPen(headerTxtColor);
        painter.setRenderHint(QPainter::TextAntialiasing);
        auto min = std::min(col, (int)title.size());
        for (int idx = 0; idx < min; ++idx)
        {
            auto txt = title[idx];
            painter.drawText(idx * cellW, 0, cellW, headerH
                , Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap
                , QString::fromLocal8Bit(txt.c_str()));
        }
    
        // content
        auto isEven = [](int n) { return n % 2 == 0; };
        for (int idx = 0; idx < row; ++idx)
        {
            int upperY = headerH + idx * cellH;
    
            painter.setPen(Qt::NoPen);
            painter.setBrush(isEven(idx) ? evenBkColor : oddBkColor);
            painter.drawRect(0, upperY, thisW - 1, headerH - 1);
    
            painter.setPen(borderColor);
            painter.setBrush(Qt::NoBrush);
            painter.drawLine(0, upperY - 1, thisW - 1, upperY - 1);
        }
    
        // border
        painter.setPen(borderColor);
        painter.setBrush(Qt::NoBrush);
        painter.drawRect(0, 0, thisW - 1, thisH - 1);
    
        bkCache.swap(bk);
    }
    
    bool QPlainStyleTable::BkSizeIsSame()
    {
        return bkCache.size() == size();
    }
    
    CellEditCallBack QPlainStyleTable::IsEditable(int row, int col)
    {
        for (auto& p: callbacks)
        {
            if (p.first.row == row 
                && p.first.col == col)
            {
                return p.second;
            }
        }
    
        return nullptr;
    }
    
    void QPlainStyleTable::SetUnEditable(int row, int col)
    {
        callbacks.erase(EditableCell{row, col});
    }
    
    void QPlainStyleTable::UpdateContent(int row, int col, const std::string& content)
    {
        bool found{ false };
        for (int idx =0 ; idx < contents.size(); ++idx)
        {
            auto& oneRow = contents[idx];
            for (int idy = 0; idy < oneRow.size(); ++idy)
            {
                if (idx == row && idy == col)
                {
                    found = true;
                    auto& old = oneRow[idy];
                    old = content;
                    break;
                }
            }
        }
    
        if (found)
        {
           update();
        }
    }
    
    jsulmJ 1 Reply Last reply
    0
    • X xce1

      UPDATE:
      After tested with a simpler QWidget subclass, I realized may be it's not a drawText problem.
      I've removed the colorful gifs, but keep the last two gray or white gifs to better demonstrate the problem.

      the original post:
      I try to implement a simple table drawing widget by overriding the QWidget:PaintEvent method.
      Now I find that, before the text and color shows up, the window is about 1 second visible blank.
      This is the gif that shows the blank.
      Using VS2019 Perfomance Profiling Tools, We can see drawText occupies about 30% ~ 50% cpu work. And if I removed all the text
      drawing, the visible blank disappears.
      cb8f3cc3-f9e4-4359-aa38-6d11d5b32433-图片.png

      Here is my code.
      main.cpp

      #include <QtWidgets/QApplication>
      #include "QPlainStyleTable.h"
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
      
          auto _m_pTable = new QPlainStyleTable();
          _m_pTable->SetHeaderColor(Qt::red, Qt::green);
          _m_pTable->SetContentColor(Qt::gray, Qt::yellow, Qt::blue);
          _m_pTable->SetBorderColor(Qt::white);
          _m_pTable->SetFont(QFont("微软雅黑"), QFont("微软雅黑"));
      
          _m_pTable->SetDimension(8, 6);
      
          _m_pTable->SetTitle({ "姓名", "年龄", "性别", "学历", "籍贯" });
          _m_pTable->AddData({ "小红", "28", "女", "大学", "山东" });
          _m_pTable->AddData({ "姓名", "年龄", "性别", "学历", "籍贯" });
          _m_pTable->AddData({ "姓名", "年龄", "性别", "学历", "籍贯" });
          _m_pTable->AddData({ "姓名", "年龄", "性别", "学历", "籍贯" });
          _m_pTable->show();
          return a.exec();
      }
      
      

      QPlainStyleTable.h

      #pragma once
      
      #include <vector>
      #include <string>
      #include <functional>
      #include <map>
      #include <memory>
      
      #include <QWidget>
      #include <QPixmap>
      #include <QColor>
      #include <QFont>
      #include <QMenu>
      
      //返回true即不再可编辑
      using CellEditCallBack = std::function<void(int mouseX, int mouseY)>;
      
      class QPlainStyleTable : public QWidget
      {
          Q_OBJECT
      
      public:
          QPlainStyleTable(QWidget *parent = nullptr);
          ~QPlainStyleTable();
      
          void SetHeaderColor(const QColor& bkColor, const QColor& txtColor);
          void SetContentColor(const QColor& evenBkColor, const QColor& oddBkColor, const QColor& txtColor);
          void SetBorderColor(const QColor& color);
          void SetFont(const QFont& headerFont, const QFont& contentFont);
          void SetDimension(int row, int col);
      
          void SetTitle(const std::vector<std::string>& title);
          void AddData(const std::vector<std::string>& row);
          void ClearContent();
      
          void SetCellEditCallBack(int row, int col, CellEditCallBack callback);
          void SetUnEditable(int row, int col);
          void UpdateContent(int row, int col, const std::string& content);
      protected:
          virtual void paintEvent(QPaintEvent *event) override;
          virtual bool eventFilter(QObject *watched, QEvent *event) override;
      private:
          //缓存背景
          QPixmap bkCache;
          void DrawBk();
          bool BkSizeIsSame();
      
          //行列
          int row;
          int col;
      
          //单元格大小, 在画背景时计算出
          int headerH;
          int tailW;
          int cellH;
          int cellW;
      
          QColor headerBkColor;
          QColor headerTxtColor;
      
          QColor contentTxtColor;
          QColor evenBkColor;
          QColor oddBkColor;
          QColor borderColor;
      
          QFont headerFont;
          QFont contentFont;
      
          // headerText
          std::vector<std::string> title;
      
          // contentText
          std::vector<std::vector<std::string>> contents;
      
          struct EditableCell
          {
              int row;
              int col;
              bool operator<(const EditableCell& rhs) const
              {
                  if (row == rhs.row)
                  {
                      return col < rhs.col;
                  }
                  else if (col == rhs.col)
                  {
                      return row < rhs.row;
                  }
      
                  return false;
              }
          };
      
          std::map<EditableCell, CellEditCallBack> callbacks;
          CellEditCallBack IsEditable(int row, int col);
      };
      
      

      QPlainStyleTable.cpp

      
      #include <algorithm>
      
      #include <QEvent>
      #include <QMouseEvent>
      #include <QPainter>
      #include "QPlainStyleTable.h"
      
      
      QPlainStyleTable::QPlainStyleTable(QWidget *parent)
          : QWidget(parent), row(0), col(0), cellW(0), cellH(0)
      {
          installEventFilter(this);
      }
      
      QPlainStyleTable::~QPlainStyleTable()
      {
      
      }
      
      void QPlainStyleTable::SetHeaderColor(const QColor& bkColor, const QColor& txtColor)
      {
          headerBkColor = bkColor;
          headerTxtColor = txtColor;
      }
      
      void QPlainStyleTable::SetContentColor(const QColor& evenBkColor, const QColor& oddBkColor, const QColor& txtColor)
      {
          this->evenBkColor = evenBkColor;
          this->oddBkColor = oddBkColor;
      
          this->contentTxtColor = txtColor;
      }
      
      void QPlainStyleTable::SetBorderColor(const QColor& color)
      {
          this->borderColor = color;
      }
      
      void QPlainStyleTable::SetFont(const QFont& headerFont, const QFont& contentFont)
      {
          this->headerFont = headerFont;
          this->contentFont = contentFont;
      }
      
      void QPlainStyleTable::SetDimension(int row, int col)
      {
          this->row = row;
          this->col = col;
      }
      
      void QPlainStyleTable::SetTitle(const std::vector<std::string>& title)
      {
          this->title = title;
      }
      
      void QPlainStyleTable::AddData(const std::vector<std::string>& row)
      {
          this->contents.push_back(row);
          update();
      }
      
      void QPlainStyleTable::ClearContent()
      {
          this->contents.clear();
          this->callbacks.clear();
          update();
      }
      
      void QPlainStyleTable::SetCellEditCallBack(int row, int col, CellEditCallBack callback)
      {
           callbacks[EditableCell{ row, col}] = callback;
      }
      
      void QPlainStyleTable::paintEvent(QPaintEvent *event)
      {
          if (bkCache.isNull())
          {
              DrawBk();
          }
          else
          {
              if (!BkSizeIsSame())
              {
                  DrawBk();
              }
          }
      
          QPainter painter(this);
          painter.drawPixmap(rect(), bkCache);
      
          // DrawContentTxt
          painter.setFont(contentFont);
          painter.setPen(contentTxtColor);
          auto showRows = std::min((int)contents.size(), row);
          for (int idx = 0; idx < showRows; ++idx)
          {
              auto& oneRow = contents[idx];
              auto showCols = std::min((int)oneRow.size(), col);
              for (int idy = 0; idy < showCols; ++idy)
              {
                  auto& txt = oneRow[idy];
                  //painter.setPen(contentTxtColor);
                  painter.setClipping(true);
                  painter.drawText(idy * cellW, idx* cellH + headerH, cellW, cellH,
                      Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap
                      , QString::fromLocal8Bit(txt.c_str()));
      
                  if (IsEditable(idx, idy))
                  {
                      painter.setPen(Qt::red);
                      painter.setRenderHint(QPainter::Antialiasing);
                      painter.drawRoundedRect(idy * cellW, idx * cellH + headerH, cellW, cellH
                          , 2, 2);
                  }
              }
          }
      }
      
      bool QPlainStyleTable::eventFilter(QObject *watched, QEvent *event)
      {
          if (watched == this
              && event->type() == QEvent::MouseButtonDblClick)
          {
              auto theEvent = (QMouseEvent*)event;
              auto x = theEvent->x();
              auto y = theEvent->y();
      
              auto clickRow = y < headerH ? -1 : (y - headerH) / cellH;
              auto clickCol = x / cellW;
              auto callback = IsEditable(clickRow, clickCol);
              if (callback)
              {
                  auto globalPos = theEvent->globalPos();
                  callback(globalPos.x(), globalPos.y());
              }
      
              return true;
          }
      
          return QWidget::eventFilter(watched, event);
      }
      
      void QPlainStyleTable::DrawBk()
      {
          QPixmap bk(width(), height());
      
          auto thisW = bk.width();
          auto thisH = bk.height();
          cellH = thisH / (row + 1);
          cellW = thisW / col;
          headerH = thisH - (cellH * row);
          tailW = thisW - (cellW * col);
      
          QPainter painter(&bk);
          painter.setPen(Qt::NoPen);
      
          // header
          painter.setBrush(headerBkColor);
          painter.drawRect(0, 0, thisW - 1, headerH - 1);
      
          headerFont.setHintingPreference(QFont::PreferNoHinting);
          painter.setFont(headerFont);
          painter.setPen(headerTxtColor);
          painter.setRenderHint(QPainter::TextAntialiasing);
          auto min = std::min(col, (int)title.size());
          for (int idx = 0; idx < min; ++idx)
          {
              auto txt = title[idx];
              painter.drawText(idx * cellW, 0, cellW, headerH
                  , Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap
                  , QString::fromLocal8Bit(txt.c_str()));
          }
      
          // content
          auto isEven = [](int n) { return n % 2 == 0; };
          for (int idx = 0; idx < row; ++idx)
          {
              int upperY = headerH + idx * cellH;
      
              painter.setPen(Qt::NoPen);
              painter.setBrush(isEven(idx) ? evenBkColor : oddBkColor);
              painter.drawRect(0, upperY, thisW - 1, headerH - 1);
      
              painter.setPen(borderColor);
              painter.setBrush(Qt::NoBrush);
              painter.drawLine(0, upperY - 1, thisW - 1, upperY - 1);
          }
      
          // border
          painter.setPen(borderColor);
          painter.setBrush(Qt::NoBrush);
          painter.drawRect(0, 0, thisW - 1, thisH - 1);
      
          bkCache.swap(bk);
      }
      
      bool QPlainStyleTable::BkSizeIsSame()
      {
          return bkCache.size() == size();
      }
      
      CellEditCallBack QPlainStyleTable::IsEditable(int row, int col)
      {
          for (auto& p: callbacks)
          {
              if (p.first.row == row 
                  && p.first.col == col)
              {
                  return p.second;
              }
          }
      
          return nullptr;
      }
      
      void QPlainStyleTable::SetUnEditable(int row, int col)
      {
          callbacks.erase(EditableCell{row, col});
      }
      
      void QPlainStyleTable::UpdateContent(int row, int col, const std::string& content)
      {
          bool found{ false };
          for (int idx =0 ; idx < contents.size(); ++idx)
          {
              auto& oneRow = contents[idx];
              for (int idy = 0; idy < oneRow.size(); ++idy)
              {
                  if (idx == row && idy == col)
                  {
                      found = true;
                      auto& old = oneRow[idy];
                      old = content;
                      break;
                  }
              }
          }
      
          if (found)
          {
             update();
          }
      }
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @xce1 said in Painter::DrawText is very slow:

      QString::fromLocal8Bit(txt.c_str())

      Why?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      X 1 Reply Last reply
      0
      • jsulmJ jsulm

        @xce1 said in Painter::DrawText is very slow:

        QString::fromLocal8Bit(txt.c_str())

        Why?

        X Offline
        X Offline
        xce1
        wrote on last edited by
        #3

        @jsulm
        I use VS2019 IDE, with multibyte charset and need show some chinese characters.

        I just tried QString::(txt.c_str()), still has the problem.

        jsulmJ 1 Reply Last reply
        0
        • X xce1

          @jsulm
          I use VS2019 IDE, with multibyte charset and need show some chinese characters.

          I just tried QString::(txt.c_str()), still has the problem.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @xce1 There is no need for txt.c_str() at all! txt is already a QString which is UTF-16 and can handle Chinese.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          X 1 Reply Last reply
          0
          • jsulmJ jsulm

            @xce1 There is no need for txt.c_str() at all! txt is already a QString which is UTF-16 and can handle Chinese.

            X Offline
            X Offline
            xce1
            wrote on last edited by
            #5

            @jsulm
            Thanks for your attention, but txt is really a std::string.
            The other parts of the program uses c++ std lib mostly, so here I used std::vector<std::vector<std::string>> contents; to store cell strings.

            I just upload the gif, which shows what I described as drawText is slow.
            Would you help me with that?

            Best regards.

            jsulmJ 1 Reply Last reply
            0
            • X xce1

              @jsulm
              Thanks for your attention, but txt is really a std::string.
              The other parts of the program uses c++ std lib mostly, so here I used std::vector<std::vector<std::string>> contents; to store cell strings.

              I just upload the gif, which shows what I described as drawText is slow.
              Would you help me with that?

              Best regards.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @xce1 https://doc.qt.io/qt-5/qstring.html#fromStdString

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              4
              • X Offline
                X Offline
                xce1
                wrote on last edited by xce1
                #7

                I've replaced all std::strings to QString, and change VS2019 charset to utf, and only use ASCII chars in string.
                Still there is a visible blank before the custom tables shows.

                Even there is only one column, one row.

                JonBJ 1 Reply Last reply
                0
                • X xce1

                  I've replaced all std::strings to QString, and change VS2019 charset to utf, and only use ASCII chars in string.
                  Still there is a visible blank before the custom tables shows.

                  Even there is only one column, one row.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @xce1
                  Your post is hurting my eyes! :( :)

                  X 1 Reply Last reply
                  1
                  • X Offline
                    X Offline
                    xce1
                    wrote on last edited by
                    #9

                    I've tested it with a single drawText call in paintEvent, the problem still exists.
                    But if I put a label on widget, the problem disappears!
                    main.cpp

                    #include <QtWidgets/QApplication>
                    #include "QPlainStyleTable.h"
                    #include "QtClass.h"
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication a(argc, argv);
                    
                    //     auto _m_pTable = new QPlainStyleTable();
                    //     _m_pTable->SetHeaderColor(Qt::red, Qt::green);
                    //     _m_pTable->SetContentColor(Qt::gray, Qt::yellow, Qt::blue);
                    //     _m_pTable->SetBorderColor(Qt::white);
                    //     //_m_pTable->SetFont(QFont(u8"微软雅黑"), QFont(u8"微软雅黑"));
                    // 
                    //     _m_pTable->SetDimension(1, 1);
                    // 
                    //     _m_pTable->SetTitle({ "a", "b", "c", "d", "e" });
                    //     _m_pTable->AddData({ "a1", "b1", "c1", "d1", "e1`" });
                    //     _m_pTable->AddData({ "a2", "b2", "c2", "d2", "e2" });
                    //     _m_pTable->AddData({ "a3", "b3", "c3", "d3", "e3" });
                    //     _m_pTable->AddData({ "a4", "b4", "c4", "d4", "e4" });
                    //     
                    //     _m_pTable->show();
                        auto _m_pQClass = new QtClass(nullptr);
                        _m_pQClass->setFixedSize(500, 400);
                        _m_pQClass->show();
                        return a.exec();
                    }
                    

                    QtClass.h

                    #pragma once
                    
                    #include <QWidget>
                    
                    class QtClass : public QWidget
                    {
                        Q_OBJECT
                    
                    public:
                        QtClass(QWidget *parent);
                        ~QtClass();
                    
                        void paintEvent(QPaintEvent* e) override;
                    };
                    
                    

                    QtClass.cpp with QLabel commented out.

                    #include "QtClass.h"
                    
                    #include <QPainter>
                    #include <QLabel>
                    
                    QtClass::QtClass(QWidget *parent)
                        : QWidget(parent)
                    {
                    //     auto _pLabel = new QLabel(this);
                    //     _pLabel->setText("HELLO WORLD!");
                    //     _pLabel->move(200, 300);
                    }
                    
                    QtClass::~QtClass()
                    {
                    }
                    
                    void QtClass::paintEvent(QPaintEvent* e)
                    {
                        QPainter painter(this);
                        painter.drawText(0, 0, 100, 200, Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap, QString("Hello World!"));
                    }
                    

                    test4.gif

                    QtClass.cpp with QLabel .

                    #include "QtClass.h"
                    
                    #include <QPainter>
                    #include <QLabel>
                    
                    QtClass::QtClass(QWidget *parent)
                        : QWidget(parent)
                    {
                        auto _pLabel = new QLabel(this);
                        _pLabel->setText("HELLO WORLD!");
                        _pLabel->move(200, 300);
                    }
                    
                    QtClass::~QtClass()
                    {
                    }
                    
                    void QtClass::paintEvent(QPaintEvent* e)
                    {
                        QPainter painter(this);
                        painter.drawText(0, 0, 100, 200, Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap, QString("Hello World!"));
                    }
                    

                    test5.gif

                    X 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @xce1
                      Your post is hurting my eyes! :( :)

                      X Offline
                      X Offline
                      xce1
                      wrote on last edited by
                      #10

                      @JonB Sorry about that. I've removed the colorful gifs.

                      @jsulm Perhaps It's not drawText problem.
                      To better demonstrate the situation, I've upload two new comparable gray gifs with a simpler QWidget subclass.

                      1 Reply Last reply
                      1
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        Hi,

                        Something just came to mind: maybe QStaticText might be of interest.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        X 1 Reply Last reply
                        0
                        • SGaistS SGaist

                          Hi,

                          Something just came to mind: maybe QStaticText might be of interest.

                          X Offline
                          X Offline
                          xce1
                          wrote on last edited by
                          #12

                          @SGaist Hi, thanks. I just tried that, It's still the same.

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            I've no performance problem with your code on linux and windows7 (both in a VM, 64bit, Qt5.15.x)

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            X 1 Reply Last reply
                            0
                            • X xce1

                              I've tested it with a single drawText call in paintEvent, the problem still exists.
                              But if I put a label on widget, the problem disappears!
                              main.cpp

                              #include <QtWidgets/QApplication>
                              #include "QPlainStyleTable.h"
                              #include "QtClass.h"
                              
                              int main(int argc, char *argv[])
                              {
                                  QApplication a(argc, argv);
                              
                              //     auto _m_pTable = new QPlainStyleTable();
                              //     _m_pTable->SetHeaderColor(Qt::red, Qt::green);
                              //     _m_pTable->SetContentColor(Qt::gray, Qt::yellow, Qt::blue);
                              //     _m_pTable->SetBorderColor(Qt::white);
                              //     //_m_pTable->SetFont(QFont(u8"微软雅黑"), QFont(u8"微软雅黑"));
                              // 
                              //     _m_pTable->SetDimension(1, 1);
                              // 
                              //     _m_pTable->SetTitle({ "a", "b", "c", "d", "e" });
                              //     _m_pTable->AddData({ "a1", "b1", "c1", "d1", "e1`" });
                              //     _m_pTable->AddData({ "a2", "b2", "c2", "d2", "e2" });
                              //     _m_pTable->AddData({ "a3", "b3", "c3", "d3", "e3" });
                              //     _m_pTable->AddData({ "a4", "b4", "c4", "d4", "e4" });
                              //     
                              //     _m_pTable->show();
                                  auto _m_pQClass = new QtClass(nullptr);
                                  _m_pQClass->setFixedSize(500, 400);
                                  _m_pQClass->show();
                                  return a.exec();
                              }
                              

                              QtClass.h

                              #pragma once
                              
                              #include <QWidget>
                              
                              class QtClass : public QWidget
                              {
                                  Q_OBJECT
                              
                              public:
                                  QtClass(QWidget *parent);
                                  ~QtClass();
                              
                                  void paintEvent(QPaintEvent* e) override;
                              };
                              
                              

                              QtClass.cpp with QLabel commented out.

                              #include "QtClass.h"
                              
                              #include <QPainter>
                              #include <QLabel>
                              
                              QtClass::QtClass(QWidget *parent)
                                  : QWidget(parent)
                              {
                              //     auto _pLabel = new QLabel(this);
                              //     _pLabel->setText("HELLO WORLD!");
                              //     _pLabel->move(200, 300);
                              }
                              
                              QtClass::~QtClass()
                              {
                              }
                              
                              void QtClass::paintEvent(QPaintEvent* e)
                              {
                                  QPainter painter(this);
                                  painter.drawText(0, 0, 100, 200, Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap, QString("Hello World!"));
                              }
                              

                              test4.gif

                              QtClass.cpp with QLabel .

                              #include "QtClass.h"
                              
                              #include <QPainter>
                              #include <QLabel>
                              
                              QtClass::QtClass(QWidget *parent)
                                  : QWidget(parent)
                              {
                                  auto _pLabel = new QLabel(this);
                                  _pLabel->setText("HELLO WORLD!");
                                  _pLabel->move(200, 300);
                              }
                              
                              QtClass::~QtClass()
                              {
                              }
                              
                              void QtClass::paintEvent(QPaintEvent* e)
                              {
                                  QPainter painter(this);
                                  painter.drawText(0, 0, 100, 200, Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap, QString("Hello World!"));
                              }
                              

                              test5.gif

                              X Offline
                              X Offline
                              xce1
                              wrote on last edited by
                              #14
                              This post is deleted!
                              1 Reply Last reply
                              0
                              • Christian EhrlicherC Christian Ehrlicher

                                I've no performance problem with your code on linux and windows7 (both in a VM, 64bit, Qt5.15.x)

                                X Offline
                                X Offline
                                xce1
                                wrote on last edited by
                                #15

                                @Christian-Ehrlicher

                                Hi, Thank you for your attention.

                                Would you please take a look at the situation below ?

                                @xce1 said in How can I replce Qpainter::drawText with a more effecient way to draw text in a table cell:

                                I've tested it with a single drawText call in paintEvent, the problem still exists.
                                But if I put a label on widget, the problem disappears!
                                main.cpp

                                #include <QtWidgets/QApplication>
                                #include "QPlainStyleTable.h"
                                #include "QtClass.h"
                                
                                int main(int argc, char *argv[])
                                {
                                    QApplication a(argc, argv);
                                
                                //     auto _m_pTable = new QPlainStyleTable();
                                //     _m_pTable->SetHeaderColor(Qt::red, Qt::green);
                                //     _m_pTable->SetContentColor(Qt::gray, Qt::yellow, Qt::blue);
                                //     _m_pTable->SetBorderColor(Qt::white);
                                //     //_m_pTable->SetFont(QFont(u8"微软雅黑"), QFont(u8"微软雅黑"));
                                // 
                                //     _m_pTable->SetDimension(1, 1);
                                // 
                                //     _m_pTable->SetTitle({ "a", "b", "c", "d", "e" });
                                //     _m_pTable->AddData({ "a1", "b1", "c1", "d1", "e1`" });
                                //     _m_pTable->AddData({ "a2", "b2", "c2", "d2", "e2" });
                                //     _m_pTable->AddData({ "a3", "b3", "c3", "d3", "e3" });
                                //     _m_pTable->AddData({ "a4", "b4", "c4", "d4", "e4" });
                                //     
                                //     _m_pTable->show();
                                    auto _m_pQClass = new QtClass(nullptr);
                                    _m_pQClass->setFixedSize(500, 400);
                                    _m_pQClass->show();
                                    return a.exec();
                                }
                                

                                QtClass.h

                                #pragma once
                                
                                #include <QWidget>
                                
                                class QtClass : public QWidget
                                {
                                    Q_OBJECT
                                
                                public:
                                    QtClass(QWidget *parent);
                                    ~QtClass();
                                
                                    void paintEvent(QPaintEvent* e) override;
                                };
                                
                                

                                QtClass.cpp with QLabel commented out.

                                #include "QtClass.h"
                                
                                #include <QPainter>
                                #include <QLabel>
                                
                                QtClass::QtClass(QWidget *parent)
                                    : QWidget(parent)
                                {
                                //     auto _pLabel = new QLabel(this);
                                //     _pLabel->setText("HELLO WORLD!");
                                //     _pLabel->move(200, 300);
                                }
                                
                                QtClass::~QtClass()
                                {
                                }
                                
                                void QtClass::paintEvent(QPaintEvent* e)
                                {
                                    QPainter painter(this);
                                    painter.drawText(0, 0, 100, 200, Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap, QString("Hello World!"));
                                }
                                

                                test4.gif

                                QtClass.cpp with QLabel .

                                #include "QtClass.h"
                                
                                #include <QPainter>
                                #include <QLabel>
                                
                                QtClass::QtClass(QWidget *parent)
                                    : QWidget(parent)
                                {
                                    auto _pLabel = new QLabel(this);
                                    _pLabel->setText("HELLO WORLD!");
                                    _pLabel->move(200, 300);
                                }
                                
                                QtClass::~QtClass()
                                {
                                }
                                
                                void QtClass::paintEvent(QPaintEvent* e)
                                {
                                    QPainter painter(this);
                                    painter.drawText(0, 0, 100, 200, Qt::AlignCenter | Qt::TextSingleLine | Qt::TextDontClip | Qt::TextWordWrap, QString("Hello World!"));
                                }
                                

                                test5.gif

                                1 Reply Last reply
                                0
                                • Christian EhrlicherC Offline
                                  Christian EhrlicherC Offline
                                  Christian Ehrlicher
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  @xce1 said in How can I replce Qpainter::drawText with a more effecient way to draw text in a table cell:

                                  Would you please take a look at the situation below ?

                                  That's the same code as above.

                                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                  Visit the Qt Academy at https://academy.qt.io/catalog

                                  X 1 Reply Last reply
                                  0
                                  • Christian EhrlicherC Christian Ehrlicher

                                    @xce1 said in How can I replce Qpainter::drawText with a more effecient way to draw text in a table cell:

                                    Would you please take a look at the situation below ?

                                    That's the same code as above.

                                    X Offline
                                    X Offline
                                    xce1
                                    wrote on last edited by
                                    #17

                                    @Christian-Ehrlicher
                                    Yes. It is. I thought maybe you missed the last post. Sorry about that.

                                    I used Qt5.14.2 on Win10 VS2019.

                                    Since no one else has the same problem. I'm about to just put a QLabel or other Qt widget to bypass it.

                                    Thank you anyway.

                                    J.HilkJ 1 Reply Last reply
                                    0
                                    • X xce1

                                      @Christian-Ehrlicher
                                      Yes. It is. I thought maybe you missed the last post. Sorry about that.

                                      I used Qt5.14.2 on Win10 VS2019.

                                      Since no one else has the same problem. I'm about to just put a QLabel or other Qt widget to bypass it.

                                      Thank you anyway.

                                      J.HilkJ Offline
                                      J.HilkJ Offline
                                      J.Hilk
                                      Moderators
                                      wrote on last edited by
                                      #18

                                      @xce1 have you tried a release build with O3 ? maybe its just a debug/development issue


                                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                      Q: What's that?
                                      A: It's blue light.
                                      Q: What does it do?
                                      A: It turns blue.

                                      X 1 Reply Last reply
                                      0
                                      • J.HilkJ J.Hilk

                                        @xce1 have you tried a release build with O3 ? maybe its just a debug/development issue

                                        X Offline
                                        X Offline
                                        xce1
                                        wrote on last edited by
                                        #19

                                        @J-Hilk I just tried that. It's the same as no debug.
                                        There is a visible blank background before "Hello World" shows up
                                        if I didn't add a QLabel in QtClass constructor.
                                        Thank you!

                                        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