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.
  • canellasC Offline
    canellasC Offline
    canellas
    wrote on 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!

    Axel SpoerlA 1 Reply Last reply
    0
    • canellasC canellas

      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!

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

      @canellas
      Could you please share the code?

      Software Engineer
      The Qt Company, Oslo

      canellasC 1 Reply Last reply
      0
      • Axel SpoerlA Axel Spoerl

        @canellas
        Could you please share the code?

        canellasC Offline
        canellasC Offline
        canellas
        wrote on 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);
        }
        
        SGaistS 1 Reply Last reply
        0
        • canellasC canellas

          @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);
          }
          
          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on 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

          Axel SpoerlA 1 Reply Last reply
          1
          • SGaistS SGaist

            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.

            Axel SpoerlA Offline
            Axel SpoerlA Offline
            Axel Spoerl
            Moderators
            wrote on 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

            canellasC 1 Reply Last reply
            0
            • Axel SpoerlA Axel Spoerl

              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.

              canellasC Offline
              canellasC Offline
              canellas
              wrote on 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?

              Axel SpoerlA 1 Reply Last reply
              0
              • canellasC canellas

                @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?

                Axel SpoerlA Offline
                Axel SpoerlA Offline
                Axel Spoerl
                Moderators
                wrote on 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

                • Login

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