Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) QtRoundedTextRectItem

 

QtQt CreatorLubuntu

 

QtRoundedEditRectItem is a Qt QGraphicsItem class that displays a rounded rectangle with text.

Technical facts

 

 

 

 

 

 

./CppQtRoundedTextRectItem/CppQtRoundedTextRectItem.pri

 

INCLUDEPATH += \
    ../../Classes/CppQtRoundedTextRectItem

SOURCES += \
    ../../Classes/CppQtRoundedTextRectItem/qtroundedtextrectitem.cpp

HEADERS  += \
    ../../Classes/CppQtRoundedTextRectItem/qtroundedtextrectitem.h

OTHER_FILES += \
    ../../Classes/CppQtRoundedTextRectItem/Licence.txt

 

 

 

 

 

./CppQtRoundedTextRectItem/qtroundedtextrectitem.h

 

//---------------------------------------------------------------------------
/*
QtRoundedTextRectItem, rectangular-shaped multi-line QGraphicsItem
Copyright (C) 2012-2014 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppQtRoundedTextRectItem.htm
//---------------------------------------------------------------------------
#ifndef QTROUNDEDTEXTRECTITEM_H
#define QTROUNDEDTEXTRECTITEM_H

#include <string>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <boost/signals2.hpp>

#include <QFont>

#include "qtroundedrectitem.h"
#pragma GCC diagnostic pop

namespace ribi {

///A QtRoundedTextItem displays a single line of text
///For multiple lines of text, use QtRoundedEditRectItem
struct QtRoundedTextRectItem : public QtRoundedRectItem
{
  struct Padding
  {
    Padding(const double any_top = 0.0, const double any_right = 0.0, const double any_bottom = 0.0, const double any_left = 0.0)
      : bottom(any_bottom), left(any_left), right(any_right), top(any_top) {}
    double bottom;
    double left;
    double right;
    double top;
  };

  QtRoundedTextRectItem(
    const std::string& text = "...",
    const Padding& padding = Padding(),
    const QFont& font = QFont("monospace",9),
    QGraphicsItem* parent = 0);

  ///ABC must have public virtual destructor
  virtual ~QtRoundedTextRectItem() noexcept {}

  ///Get the font by which the text is drawn
  const QFont& GetFont() const noexcept { return m_font; }

  ///Get the text
  const std::string& GetText() const noexcept { return m_text; }

  ///Obtain the version of this class
  static std::string GetVersion() noexcept;

  ///Obtain the version history of this class
  static std::vector<std::string> GetVersionHistory() noexcept;

  ///Set the font by which the text is drawn
  void SetFont(const QFont& font) noexcept;

  ///Set the padding between text and rectangle
  void SetPadding(const Padding& padding) noexcept;

  ///Set the text displayed
  void SetText(const std::string& text) noexcept;

  ///Set the pen by which the text is drawn
  void SetTextPen(const QPen& pen) noexcept;

protected:
  virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) noexcept;
  virtual void keyPressEvent(QKeyEvent* event);

private:
  ///The font by which the text is drawn
  QFont m_font;

  ///Set the padding between text and rectangle
  Padding m_padding;

  ///The text displayed
  std::string m_text;

  ///The pen by which the text is drawn
  QPen m_text_pen;

  ///Set the padding around text, so the text will be centered
  static const Padding m_text_padding;

  ///Obtain the padded text rectangle
  const QRectF GetPaddedTextRect() const;

  ///Obtain the unpadded text rectangle
  ///Note: even this rectangle is enlarged by a pixel in both dimensions, so the text will be drawn in full
  const QRectF GetTextRect() const;

  ///Height of this item is determined by the text
  void SetHeight(const double width) = delete;

  ///Width of this item is determined by the text
  void SetWidth(const double width) = delete;

};

} //~namespace ribi

#endif // QTROUNDEDTEXTRECTITEM_H

 

 

 

 

 

./CppQtRoundedTextRectItem/qtroundedtextrectitem.cpp

 

//---------------------------------------------------------------------------
/*
QtRoundedTextRectItem, rectangular-shaped multi-line QGraphicsItem
Copyright (C) 2012-2014 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppQtRoundedTextRectItem.htm
//---------------------------------------------------------------------------
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include "qtroundedtextrectitem.h"

#include <cassert>
#include <sstream>
#include <QBrush>
#include <QFont>
#include <QGraphicsScene>
#include <QKeyEvent>
#include <QInputDialog>
#include <QPainter>

//#include "trace.h"
#pragma GCC diagnostic pop

const ribi::QtRoundedTextRectItem::Padding ribi::QtRoundedTextRectItem::m_text_padding(3.0,0.0,0.0,3.0);

ribi::QtRoundedTextRectItem::QtRoundedTextRectItem(
  const std::string& text,
  const Padding& padding,
  const QFont& font,
  QGraphicsItem* parent)
  : QtRoundedRectItem(parent),
    m_font(font),
    m_padding(padding),
    m_text{}, //Empty std::string, as m_text must be set by SetText
    m_text_pen{}
{
  this->setFlags(
      QGraphicsItem::ItemIsFocusable
    | QGraphicsItem::ItemIsMovable
    | QGraphicsItem::ItemIsSelectable);

  ///Obtain a white background
  this->setBrush(QBrush(QColor(255,255,255)));

  this->SetFont(font);
  this->SetRadiusX(4.0);
  this->SetRadiusY(4.0);
  this->SetText(text);

}

const QRectF ribi::QtRoundedTextRectItem::GetPaddedTextRect() const
{
  return GetTextRect().adjusted(
    -m_text_padding.left,
    -m_text_padding.top,
     m_text_padding.right,
     m_text_padding.bottom);
}

const QRectF ribi::QtRoundedTextRectItem::GetTextRect() const
{
  const double h = QFontMetricsF(m_font).height();
  const double w = QFontMetricsF(m_font).width(m_text.c_str());
  #ifdef _WIN32
  //adjusted(0.0,0.0,2.0,0.0) works fine for 50% of the fonts supplied by Wine under native Lubuntu
  //adjusted(0.0,0.0,3.0,0.0) works fine for 80% of the fonts supplied by Wine under native Lubuntu
  return QRectF(-0.5 * w, -0.5 * h,w,h).adjusted(0.0,0.0,3.0,0.0);
  #else
  //adjusted(0.0,0.0,2.0,-1.0) works fine for 90% of the fonts under native Lubuntu
  //adjusted(0.0,0.0,3.0,-1.0) works fine for 99% of the fonts under native Lubuntu
  //adjusted(0.0,0.0,4.0,-1.0) works fine for all the fonts I've tried under native Lubuntu
  return QRectF(-0.5 * w, -0.5 * h,w,h).adjusted(0.0,0.0,2.0,-1.0);
  #endif
}

std::string ribi::QtRoundedTextRectItem::GetVersion() noexcept
{
  return "1.3";
}

std::vector<std::string> ribi::QtRoundedTextRectItem::GetVersionHistory() noexcept
{
  return {
    "2012-12-19: version 1.0: initial version",
    "2012-12-20: version 1.1: added response to key press, text is displayed fully",
    "2012-12-21: version 1.2: added debug drawing, text is displayed correctly to the pixel",
    "2012-12-28: version 1.3: fixed incomplete displaying when using Wine",
  };
}

void ribi::QtRoundedTextRectItem::keyPressEvent(QKeyEvent* event)
{
  switch (event->key())
  {
    case Qt::Key_F2:
    {
      bool ok = true;
      const QString s = QInputDialog::getText(0,"Edit text","New text",QLineEdit::Normal,m_text.c_str(),&ok);
      if (ok) SetText(s.toStdString());
    }
    break;
  }
  QtRoundedRectItem::keyPressEvent(event);
}

void ribi::QtRoundedTextRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) noexcept
{
  QtRoundedRectItem::paint(painter,option,widget);
  painter->setFont(m_font);
  //#define DISPLAY_DIFFERENT_RECTS_873658735672347834573985792
  #ifdef  DISPLAY_DIFFERENT_RECTS_873658735672347834573985792
  painter->setBrush(QBrush(QColor(255,0,0)));
  painter->drawRect(this->GetPaddedTextRect());
  painter->setBrush(QBrush(QColor(0,0,255)));
  painter->drawRect(this->GetTextRect());
  #endif
  painter->setPen(m_text_pen);
  painter->drawText(GetTextRect(),m_text.c_str());
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
void ribi::QtRoundedTextRectItem::SetFont(const QFont& font) noexcept
{
  if (m_font != font)
  {
    m_font = font;
    this->update();
    //this->m_signal_item_has_updated(this);
    //m_signal_request_scene_update();
  }
}
#pragma GCC diagnostic pop

void ribi::QtRoundedTextRectItem::SetPadding(const Padding& padding) noexcept
{
  if ( padding.bottom != m_padding.bottom
    || padding.left   != m_padding.left
    || padding.right  != m_padding.right
    || padding.top    != m_padding.top
    )
  {
    m_padding = padding;
    const QRectF text_rect = GetPaddedTextRect();
    this->SetRoundedRect(
      text_rect.adjusted(
        -m_padding.left,
        -m_padding.top,
         m_padding.right,
         m_padding.bottom),
      this->GetRadiusX(),
      this->GetRadiusY()
    );
    this->update();
    //this->m_signal_item_has_updated(this);
    //m_signal_request_scene_update();
  }
}

void ribi::QtRoundedTextRectItem::SetText(const std::string& text) noexcept
{
  if (text != m_text)
  {
    m_text = text;
    const QRectF text_rect = GetPaddedTextRect();
    this->SetRoundedRect(
      text_rect.adjusted(
        -m_padding.left,
        -m_padding.top,
         m_padding.right,
         m_padding.bottom),
      this->GetRadiusX(),
      this->GetRadiusY()
    );
    this->update();
    //this->m_signal_item_has_updated(this);
    //m_signal_request_scene_update();
  }
}

void ribi::QtRoundedTextRectItem::SetTextPen(const QPen& pen) noexcept
{
  if (m_text_pen != pen)
  {
    m_text_pen = pen;
    this->update();
    //this->m_signal_item_has_updated(this);
  }
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml