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. Display only superscript char mixed with regular char in a QTableWidget

Display only superscript char mixed with regular char in a QTableWidget

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 322 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.
  • C Offline
    C Offline
    canellas
    wrote on 28 Aug 2023, 02:34 last edited by
    #1

    Hi, everyone!

    I need to display a superscript number followed by a letter in a QTableWidgetCell, and in the following cells, horizontally or vertically, display a simple char (requirement 1).

    I do want the cell to be editable (requirement 2).

    I need a arrow like cursor (requirement 3).

    I created a subclass of QTextEdit so that I could use QTextEdit::setHtml(QString) like this textEdit->setHtml("<sup>39</sup>M");. I also used text->setReadOnly(true); to disable editing.

    However, textEditor->setCursor(Qt::PointingHandCursor); does not work, as described here (issue 1).

    Another problem happens when the following cell is below the one with the superscript number: I could not align them (issue 2). I mean, they look like:

    ccbf0c91-39f6-4d2d-bdf3-2bd8e1e4ee36-image.png

    I wonder if there is a better QWidget I could derive from to satisfy the requirements without the issues.

    TIA!

    A 1 Reply Last reply 28 Aug 2023, 05:33
    0
    • C canellas
      28 Aug 2023, 02:34

      Hi, everyone!

      I need to display a superscript number followed by a letter in a QTableWidgetCell, and in the following cells, horizontally or vertically, display a simple char (requirement 1).

      I do want the cell to be editable (requirement 2).

      I need a arrow like cursor (requirement 3).

      I created a subclass of QTextEdit so that I could use QTextEdit::setHtml(QString) like this textEdit->setHtml("<sup>39</sup>M");. I also used text->setReadOnly(true); to disable editing.

      However, textEditor->setCursor(Qt::PointingHandCursor); does not work, as described here (issue 1).

      Another problem happens when the following cell is below the one with the superscript number: I could not align them (issue 2). I mean, they look like:

      ccbf0c91-39f6-4d2d-bdf3-2bd8e1e4ee36-image.png

      I wonder if there is a better QWidget I could derive from to satisfy the requirements without the issues.

      TIA!

      A Offline
      A Offline
      Axel Spoerl
      Moderators
      wrote on 28 Aug 2023, 05:33 last edited by
      #2

      @canellas
      Could you please share the code?

      Software Engineer
      The Qt Company, Oslo

      C 1 Reply Last reply 28 Aug 2023, 17:34
      0
      • A Axel Spoerl
        28 Aug 2023, 05:33

        @canellas
        Could you please share the code?

        C Offline
        C Offline
        canellas
        wrote on 28 Aug 2023, 17:34 last edited by
        #3

        @Axel-Spoerl
        The classes I created:

        class Letter : public QTextEdit {
          Q_OBJECT
        public:
          Letter() : QTextEdit(nullptr) {
            setFrameStyle(0);
            setReadOnly(true);
            setAlignment(Qt::AlignCenter);
            unsetCursor();
            setCursor(Qt::PointingHandCursor);
          }
        
          void highlight() { setTextColor(QColor(255, 255, 0)); }
        
          void lowlight() { setTextColor(QColor(255, 255, 255)); }
        };
        
        class NonFirstLetter : public Letter {
          Q_OBJECT
        public:
          NonFirstLetter(QChar p_letter) : Letter() {
            QString _str{QString{"   "} + QString(p_letter).toUpper()};
            setHtml(_str);
          }
        };
        
        class FirstLetter : public Letter {
          Q_OBJECT
        public:
          FirstLetter(int p_number, QChar p_letter) : Letter() {
            setMouseTracking(true);
        
            QString _str{"<sup>" + QString::number(p_number) + "</sup>" +
                         QString(p_letter).toUpper()};
            setHtml(_str);
          }
        
          void add_letter(NonFirstLetter *p_letter) {
            m_other_letters.push_back(p_letter);
          }
        
          void mousePressEvent(QMouseEvent * /*event*/) {
            for (auto _letter : m_other_letters) {
              _letter->highlight();
            }
          }
        
        private:
          std::vector<NonFirstLetter *> m_other_letters;
        };
        

        A simple usage:

        void MainWindow::on_pushButton_clicked() {
          ui->tableWidget->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
          ui->tableWidget->setRowCount(2);
          ui->tableWidget->setColumnCount(1);
          ui->tableWidget->setColumnWidth(0, 1);
        
          auto _first_letter{new FirstLetter{39, 'M'}};
          auto _letter{new NonFirstLetter{'A'}};
          _first_letter->add_letter(_letter);
        
          ui->tableWidget->setCellWidget(0, 0, _first_letter);
          ui->tableWidget->setCellWidget(1, 0, _letter);
        }
        
        S 1 Reply Last reply 28 Aug 2023, 18:17
        0
        • C canellas
          28 Aug 2023, 17:34

          @Axel-Spoerl
          The classes I created:

          class Letter : public QTextEdit {
            Q_OBJECT
          public:
            Letter() : QTextEdit(nullptr) {
              setFrameStyle(0);
              setReadOnly(true);
              setAlignment(Qt::AlignCenter);
              unsetCursor();
              setCursor(Qt::PointingHandCursor);
            }
          
            void highlight() { setTextColor(QColor(255, 255, 0)); }
          
            void lowlight() { setTextColor(QColor(255, 255, 255)); }
          };
          
          class NonFirstLetter : public Letter {
            Q_OBJECT
          public:
            NonFirstLetter(QChar p_letter) : Letter() {
              QString _str{QString{"   "} + QString(p_letter).toUpper()};
              setHtml(_str);
            }
          };
          
          class FirstLetter : public Letter {
            Q_OBJECT
          public:
            FirstLetter(int p_number, QChar p_letter) : Letter() {
              setMouseTracking(true);
          
              QString _str{"<sup>" + QString::number(p_number) + "</sup>" +
                           QString(p_letter).toUpper()};
              setHtml(_str);
            }
          
            void add_letter(NonFirstLetter *p_letter) {
              m_other_letters.push_back(p_letter);
            }
          
            void mousePressEvent(QMouseEvent * /*event*/) {
              for (auto _letter : m_other_letters) {
                _letter->highlight();
              }
            }
          
          private:
            std::vector<NonFirstLetter *> m_other_letters;
          };
          

          A simple usage:

          void MainWindow::on_pushButton_clicked() {
            ui->tableWidget->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
            ui->tableWidget->setRowCount(2);
            ui->tableWidget->setColumnCount(1);
            ui->tableWidget->setColumnWidth(0, 1);
          
            auto _first_letter{new FirstLetter{39, 'M'}};
            auto _letter{new NonFirstLetter{'A'}};
            _first_letter->add_letter(_letter);
          
            ui->tableWidget->setCellWidget(0, 0, _first_letter);
            ui->tableWidget->setCellWidget(1, 0, _letter);
          }
          
          S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 28 Aug 2023, 18:17 last edited by
          #4

          Hi,

          From the look of it, you should rather implement a custom QStyledItemDelegate. That way you can paint your text content the way you want it.

          This RichTextDelegate class could serve as a base.

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

          A 1 Reply Last reply 29 Aug 2023, 06:46
          1
          • S SGaist
            28 Aug 2023, 18:17

            Hi,

            From the look of it, you should rather implement a custom QStyledItemDelegate. That way you can paint your text content the way you want it.

            This RichTextDelegate class could serve as a base.

            A Offline
            A Offline
            Axel Spoerl
            Moderators
            wrote on 29 Aug 2023, 06:46 last edited by
            #5

            Fully agree with @SGaist.
            While the existing approach will actually work, its limits are Z-ordering and layouting. QStyleItemDelegate is a flexible tool and derives from the underlying data model. If the primary focus is on UI behaviour, you could also create a custom widget, that has a layout, a QLabel and a QLineEdit child. It could be used as a cell widget, if the underlying data can be handled manually.

            Software Engineer
            The Qt Company, Oslo

            C 1 Reply Last reply 30 Aug 2023, 23:56
            0
            • A Axel Spoerl
              29 Aug 2023, 06:46

              Fully agree with @SGaist.
              While the existing approach will actually work, its limits are Z-ordering and layouting. QStyleItemDelegate is a flexible tool and derives from the underlying data model. If the primary focus is on UI behaviour, you could also create a custom widget, that has a layout, a QLabel and a QLineEdit child. It could be used as a cell widget, if the underlying data can be handled manually.

              C Offline
              C Offline
              canellas
              wrote on 30 Aug 2023, 23:56 last edited by
              #6

              @Axel-Spoerl and @SGaist ,

              I am trying to avoid using [QAbstractItemDelegate](link https://doc.qt.io/qt-6/qabstractitemdelegate.html) in this [QTableWidget](link https://doc.qt.io/qt-6/qabstractitemdelegate.html), at least for now, because it would require some time for me to learn how to use it and I need a simple POC.

              I got this so far:
              4868e8e4-4855-4e0b-88db-7ed5febfbe86-image.png

              With this code:

              class Letter : public QLabel {
                Q_OBJECT
              public:
                Letter() : QLabel(nullptr) {
                  setAlignment(Qt::AlignCenter);
                  unsetCursor();
                  setCursor(Qt::PointingHandCursor);
                  setTextFormat(Qt::RichText);
                  setAlignment(Qt::AlignRight);
                }
              
                void highlight() { setStyleSheet("color: rgb(255, 0, 0);"); }
              
                void lowlight() { setStyleSheet("color: rgb(0, 0, 0);"); }
              };
              
              class NonFirstLetter : public Letter {
                Q_OBJECT
              public:
                NonFirstLetter(QChar p_letter) : Letter() {
                  QString _str{QString(p_letter).toUpper()};
                  setText(_str);
                  adjustSize();
                }
              };
              
              class FirstLetter : public Letter {
                Q_OBJECT
              public:
                FirstLetter(int p_number, QChar p_letter) : Letter() {
                  setMouseTracking(true);
              
                  QString _str{"<sup>" + QString::number(p_number) + "</sup>" +
                               QString(p_letter).toUpper()};
                  setText(_str);
                  adjustSize();
                }
              
                void add_letter(NonFirstLetter *p_letter) {
                  m_other_letters.push_back(p_letter);
                }
              
                void mousePressEvent(QMouseEvent * /*event*/) {
                  highlight();
                  for (auto _letter : m_other_letters) {
                    _letter->highlight();
                  }
                }
              
              private:
                std::vector<NonFirstLetter *> m_other_letters;
              };
              

              and

              void MainWindow::on_pushButton_clicked() {
                ui->verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
                ui->tableWidget->setRowCount(2);
                ui->tableWidget->setColumnCount(1);
                ui->tableWidget->resizeColumnsToContents();
              
                auto _first_letter{new FirstLetter{39, 'M'}};
                auto _letter{new NonFirstLetter{'A'}};
                _first_letter->add_letter(_letter);
              
                ui->tableWidget->setCellWidget(0, 0, _first_letter);
                ui->tableWidget->setCellWidget(1, 0, _letter);
              }
              

              I would like to reduce the width of the label and column just enough to display the superscript number and the letter, but I failed to do it.

              Is it possible?

              A 1 Reply Last reply 1 Sept 2023, 07:02
              0
              • C canellas
                30 Aug 2023, 23:56

                @Axel-Spoerl and @SGaist ,

                I am trying to avoid using [QAbstractItemDelegate](link https://doc.qt.io/qt-6/qabstractitemdelegate.html) in this [QTableWidget](link https://doc.qt.io/qt-6/qabstractitemdelegate.html), at least for now, because it would require some time for me to learn how to use it and I need a simple POC.

                I got this so far:
                4868e8e4-4855-4e0b-88db-7ed5febfbe86-image.png

                With this code:

                class Letter : public QLabel {
                  Q_OBJECT
                public:
                  Letter() : QLabel(nullptr) {
                    setAlignment(Qt::AlignCenter);
                    unsetCursor();
                    setCursor(Qt::PointingHandCursor);
                    setTextFormat(Qt::RichText);
                    setAlignment(Qt::AlignRight);
                  }
                
                  void highlight() { setStyleSheet("color: rgb(255, 0, 0);"); }
                
                  void lowlight() { setStyleSheet("color: rgb(0, 0, 0);"); }
                };
                
                class NonFirstLetter : public Letter {
                  Q_OBJECT
                public:
                  NonFirstLetter(QChar p_letter) : Letter() {
                    QString _str{QString(p_letter).toUpper()};
                    setText(_str);
                    adjustSize();
                  }
                };
                
                class FirstLetter : public Letter {
                  Q_OBJECT
                public:
                  FirstLetter(int p_number, QChar p_letter) : Letter() {
                    setMouseTracking(true);
                
                    QString _str{"<sup>" + QString::number(p_number) + "</sup>" +
                                 QString(p_letter).toUpper()};
                    setText(_str);
                    adjustSize();
                  }
                
                  void add_letter(NonFirstLetter *p_letter) {
                    m_other_letters.push_back(p_letter);
                  }
                
                  void mousePressEvent(QMouseEvent * /*event*/) {
                    highlight();
                    for (auto _letter : m_other_letters) {
                      _letter->highlight();
                    }
                  }
                
                private:
                  std::vector<NonFirstLetter *> m_other_letters;
                };
                

                and

                void MainWindow::on_pushButton_clicked() {
                  ui->verticalLayout->setSizeConstraint(QLayout::SetFixedSize);
                  ui->tableWidget->setRowCount(2);
                  ui->tableWidget->setColumnCount(1);
                  ui->tableWidget->resizeColumnsToContents();
                
                  auto _first_letter{new FirstLetter{39, 'M'}};
                  auto _letter{new NonFirstLetter{'A'}};
                  _first_letter->add_letter(_letter);
                
                  ui->tableWidget->setCellWidget(0, 0, _first_letter);
                  ui->tableWidget->setCellWidget(1, 0, _letter);
                }
                

                I would like to reduce the width of the label and column just enough to display the superscript number and the letter, but I failed to do it.

                Is it possible?

                A Offline
                A Offline
                Axel Spoerl
                Moderators
                wrote on 1 Sept 2023, 07:02 last edited by
                #7

                @canellas
                If the simple POC needs proper formatting, then there's no way around the right tools IMHO.
                In this case, the delegate the tool of choice. Trying to format cell content, mixed with cell widgets is drilling a wood screw into a screw nut. It will hold somehow, while looking ugly. Sorry for not being able to provide a better advice!

                Software Engineer
                The Qt Company, Oslo

                1 Reply Last reply
                0

                5/7

                29 Aug 2023, 06:46

                • Login

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