Russian Qt Forum

Qt => Вопросы новичков => Тема начата: billy4685 от Июль 31, 2020, 11:20



Название: Как в QCheckBox записать подстрочный текст?
Отправлено: billy4685 от Июль 31, 2020, 11:20
Здравствуйте, господа форумчане.

Ранее когда мне нужно было в QLabel написать подстрочный текст, я использовал тег <sub></sub>.
К примеру: T<sub>A</sub>. В результате получал в программе: TA.

Теперь пришло время, когда мне подобное нужно отображать в QCheckBox. Увы здесь оно не работает,
так как QCheckBox походу не понимает html тегов.

Есть ли способ все же заставить QCheckBox отображать подстрочный текст?


Название: Re: Как в QCheckBox записать подстрочный текст?
Отправлено: Hellraiser от Июль 31, 2020, 13:26
Немного извращенный способ: у чекбокса убрать текст, рядом расположить лабельку с нужным текстом, их поместить в горизонтальный лейаут.


Название: Re: Как в QCheckBox записать подстрочный текст?
Отправлено: billy4685 от Июль 31, 2020, 14:52
Немного извращенный способ: у чекбокса убрать текст, рядом расположить лабельку с нужным текстом, их поместить в горизонтальный лейаут.
Пока так и сделал. Думал может ещё имеется какой-то вариант.


Название: Re: Как в QCheckBox записать подстрочный текст?
Отправлено: Hellraiser от Июль 31, 2020, 15:57
Тогда наследоваться от QCheckBox`а и переопределять его paintEvent.  :)


Название: Re: Как в QCheckBox записать подстрочный текст?
Отправлено: billy4685 от Август 07, 2020, 11:10
Тогда наследоваться от QCheckBox`а и переопределять его paintEvent.  :)
Спасибо за совет.


Название: Re: Как в QCheckBox записать подстрочный текст?
Отправлено: billy4685 от Август 13, 2020, 08:57
Создал я свой виджет CheckBoxHtml из виджета QCheckBox.
Переопределил ему метод paintEvent(QPaintEvent *event). Решил зарисовать
существующий текст цветом фона виджета, а вместо него используя
QTextDocument нарисовать html документ с новым текстом.

Исходники моего виджета:
checkboxhtml.h
Код:
#ifndef CHECKBOXHTML_H
#define CHECKBOXHTML_H

#include <QCheckBox>

class CheckBoxHtml : public QCheckBox
{
Q_OBJECT

protected:
void paintEvent(QPaintEvent *event);

public:
CheckBoxHtml(QWidget *parent = 0);
};
#endif

checkboxhtml.cpp
Код:
#include "checkboxhtml.h"
#include <QPaintEvent>
#include <QTextDocument>
#include <QPainter>
#include <QStyle>

CheckBoxHtml::CheckBoxHtml(QWidget *parent) :
  QCheckBox(parent)
{

setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setMinimumSize(1, 1);

setText("CheckBox");
}

void CheckBoxHtml::paintEvent(QPaintEvent *event)
{
QCheckBox::paintEvent(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);

QFontMetrics font_metr = fontMetrics();
QRect rect_text;
QRect rect_erase;
QSize text_size = style()->itemTextRect(font_metr, QRect(), Qt::TextShowMnemonic, false, text()).size();

QSize icon_size_delta = QSize(iconSize().width(), iconSize().height());

if(layoutDirection() == Qt::LeftToRight)
  {
  rect_erase = QRect(icon_size_delta.width(), (rect().height()/2) - (text_size.height()/2),
     rect().width() - icon_size_delta.width(), text_size.height()) ;
  }
else
  {
  rect_erase = QRect(0, (rect().height()/2) - (text_size.height()/2),
     rect().width() - icon_size_delta.width(), text_size.height());
  }

QColor background_color = this->palette().background().color();
QBrush background_brush = this->palette().background();
painter.setPen(background_color);
painter.setBrush(background_brush);
painter.drawRect(rect_erase);

QTextDocument textDoc;
textDoc.setDefaultFont(this->font());
textDoc.setDefaultStyleSheet("html {color: black; background-color: yellow;}");
textDoc.setHtml("<html>" + this->text() + "</html>");

if(layoutDirection() == Qt::LeftToRight)
  {
  rect_text = QRect(icon_size_delta.width(), (rect().height()/2) - (textDoc.size().height()/2),
    textDoc.size().width(), textDoc.size().height());
  }
else
  {
  rect_text = QRect(rect().width() - icon_size_delta.width() - textDoc.size().width(),
    (rect().height()/2) - (textDoc.size().height()/2),
    textDoc.size().width(), textDoc.size().height());
  }

painter.translate(rect_text.x(), rect_text.y());
textDoc.drawContents(&painter);
painter.end();
}

Создал новый проект ExampleCheckBox и добавил на форму свой виджет
CheckBoxHtml, и взял его в QGridLayout. Задал в дизайнере размер окна 124 x 40,
имя для виджета check_box_html, шрифт для check_box_html 12 Times New Roman
жирный, а также его текст : "A = A<sub>1</sub> + A<sub>2</sub>".
Проект прикреплю ниже.

Но теперь я столкнулся со следующей проблемой:
1. Как узнать позицию текста? Решил использовать для этого размер
иконки (iconSize()). Но к сожалению, если в стилях задать для
QCheckBox новый размер индикатора:
Код:
setStyleSheet("QCheckBox::indicator {width: 30px; height: 30px;}");
то iconSize() возвращает другой размер (тот, что задан в дизайнере
по-умолчанию 16x16, или тот, который может быть задан через
setIconSize(QSize) и в моем виджете текст наезжает на иконку).
Ниже также прикреплю рисунок.
Пока заметил только эту проблему.

Есть ли у кого-то соображения как избавится от данной проблемы.
Может кто-то посоветует, как улучшить мой виджет.