Results 1 to 2 of 2

Thread: How to create a ruler widget for a qcustomplot with a given ICSRulerWidget Class?

  1. #1
    Join Date
    Mar 2017
    Posts
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default How to create a ruler widget for a qcustomplot with a given ICSRulerWidget Class?

    I am trying to create a ruler widget that I can use to measure customplot's keys or values. I found an existing thread that included the .cpp and .h file for the ICSRulerWidget Class. However, I do not quite know to use the given class' methods to create the ruler. Specifically, I'd like it to be placed at the place the mouse was pressed, and be able to be dragged to the spot to be measured until mouse released.

    Can anyone help with a simple example of creating the ruler?

    The icsrulerwidget.cpp file:
    Qt Code:
    1. #include <QDebug>
    2. #include <QIcon>
    3. #include <QPen>
    4. #include <QPaintEvent>
    5. #include <QPainter>
    6. #include "icsrulerwidget.h"
    7.  
    8. ICSRulerWidget::ICSRulerWidget(QWidget* pParent): QWidget(pParent) {}
    9.  
    10. int ICSRulerWidget::createMarker(bool pInverted) {
    11. auto pMarker = new QLabel(this);
    12.  
    13. pMarker->installEventFilter(this);
    14. pMarker->setProperty("ICS_MarkerInverted", pInverted);
    15. pMarker->setProperty("ICS_MarkerValue", 0.0f);
    16. pMarker->setPixmap(
    17. m_nOrientation == Qt::Horizontal
    18. ? QIcon(":/resources/toolbar/rulerTool.png").pixmap(16, 16)
    19. : QIcon(":/resources/toolbar/rulerTool.png").pixmap(16, 16)
    20. );
    21.  
    22. m_lstMarkers.append(pMarker);
    23. setMarkerRange(m_lstMarkers.length() - 1, 0.0f, m_fMaximum);
    24.  
    25. return m_lstMarkers.length() - 1;
    26. }
    27.  
    28. void ICSRulerWidget::setOrientation(Qt::Orientation pOrientation) {
    29. if(pOrientation == Qt::Horizontal)
    30. setMinimumSize(0, fontMetrics().height() + 16);
    31. else
    32. setMinimumSize(fontMetrics().height() + 16, 0);
    33.  
    34. m_nOrientation = pOrientation;
    35.  
    36. updateGeometry();
    37. }
    38.  
    39. float ICSRulerWidget::markerValue(int pIndex) const { return m_lstMarkers[pIndex]->property("ICS_MarkerValue").toFloat(); }
    40.  
    41. void ICSRulerWidget::setMarkerValue(int pIndex, float pValue) {
    42. auto pMarker = m_lstMarkers[pIndex];
    43.  
    44. pMarker->setProperty("ICS_MarkerValue", pValue);
    45.  
    46. if(m_nOrientation == Qt::Horizontal)
    47. pMarker->move(
    48. pMarker->property("ICS_MarkerInverted").toBool()
    49. ? m_nOrigin + float(physicalDpiX()) / 25.4f * (m_fMaximum - pValue)
    50. : m_nOrigin + float(physicalDpiX()) / 25.4f * pValue,
    51. 0
    52. );
    53. else
    54. pMarker->move(
    55. 0,
    56. pMarker->property("ICS_MarkerInverted").toBool()
    57. ? m_nOrigin + float(physicalDpiY()) / 25.4f * (m_fMaximum - pValue)
    58. : m_nOrigin + float(physicalDpiY()) / 25.4f * pValue
    59. );
    60.  
    61. emit markerValueChanged(pIndex, pValue);
    62. }
    63.  
    64. void ICSRulerWidget::setMarkerRange(int pIndex, float pMinimum, float pMaximum) {
    65. m_lstMarkers[pIndex]->setProperty("ICS_MarkerRange", QVariant::fromValue<QPair<float, float> >(QPair<float, float>(pMinimum, pMaximum)));
    66. }
    67.  
    68. bool ICSRulerWidget::eventFilter(QObject* pSender, QEvent* pEvent) {
    69. if(auto pMarker = dynamic_cast<QLabel*>(pSender))
    70. switch(pEvent->type()) {
    71. case QEvent::MouseButtonPress: {
    72. auto pMouseEvent = dynamic_cast<QMouseEvent*>(pEvent);
    73.  
    74. if(!mouseGrabber() && pMouseEvent->button() == Qt::LeftButton) {
    75. pMarker->grabMouse();
    76. pMarker->setProperty("ICS_MouseGrabPoint", pMouseEvent->pos());
    77.  
    78. emit markerValueAboutToBeChanged(m_lstMarkers.indexOf(pMarker));
    79. return true;
    80. }
    81. }
    82.  
    83. break;
    84.  
    85. case QEvent::MouseMove:
    86. if(mouseGrabber() == pMarker) {
    87. auto ptParent = pMarker->mapToParent(dynamic_cast<QMouseEvent*>(pEvent)->pos()) - pMarker->property("ICS_MouseGrabPoint").toPoint();
    88. auto cRange = pMarker->property("ICS_MarkerRange").value<QPair<float, float> >();
    89.  
    90. if(m_nOrientation == Qt::Horizontal) {
    91. if(ptParent.x() >= physicalDpiX() / 25.4f * cRange.first && ptParent.x() <= m_nOrigin + physicalDpiX() / 25.4f * cRange.second) {
    92. pMarker->move(ptParent.x(), 0);
    93.  
    94. emit markerValueChanging(
    95. m_lstMarkers.indexOf(pMarker),
    96. pMarker->property("ICS_MarkerInverted").toBool()
    97. ? m_fMaximum - float(ptParent.x() - m_nOrigin) * 25.4f / float(physicalDpiX())
    98. : float(ptParent.x() + m_nOrigin) * 25.4f / float(physicalDpiX())
    99. );
    100.  
    101. return true;
    102. }
    103. } else if(ptParent.y() >= physicalDpiY() / 25.4f * cRange.first && ptParent.y() <= m_nOrigin + physicalDpiY() / 25.4f * cRange.second) {
    104. pMarker->move(0, ptParent.y());
    105.  
    106. emit markerValueChanging(
    107. m_lstMarkers.indexOf(pMarker),
    108. pMarker->property("ICS_MarkerInverted").toBool()
    109. ? m_fMaximum - float(ptParent.y() - m_nOrigin) * 25.4f / float(physicalDpiY())
    110. : float(ptParent.y() + m_nOrigin) * 25.4f / float(physicalDpiY())
    111. );
    112.  
    113. return true;
    114. }
    115. }
    116.  
    117. break;
    118.  
    119. case QEvent::MouseButtonRelease: {
    120. auto pMouseEvent = dynamic_cast<QMouseEvent*>(pEvent);
    121. auto cRange = pMarker->property("ICS_MarkerRange").value<QPair<float, float> >();
    122.  
    123. if(mouseGrabber() == pMarker && pMouseEvent->button() == Qt::LeftButton) {
    124. auto ptParent = pMarker->mapToParent(pMouseEvent->pos()) - pMarker->property("ICS_MouseGrabPoint").toPoint();
    125.  
    126. pMarker->releaseMouse();
    127.  
    128. if(m_nOrientation == Qt::Horizontal) {
    129. if(ptParent.x() >= physicalDpiX() / 25.4f * cRange.first && ptParent.x() <= m_nOrigin + physicalDpiX() / 25.4f * cRange.second) {
    130. pMarker->move(ptParent.x(), 0);
    131. pMarker->setProperty(
    132. "ICS_MarkerValue",
    133. pMarker->property("ICS_MarkerInverted").toBool()
    134. ? m_fMaximum - float(ptParent.x() - m_nOrigin) * 25.4f / float(physicalDpiX())
    135. : float(ptParent.x() + m_nOrigin) * 25.4f / float(physicalDpiX())
    136. );
    137. }
    138. } else if(ptParent.y() >= physicalDpiY() / 25.4f * cRange.first && ptParent.y() <= m_nOrigin + physicalDpiY() / 25.4f * cRange.second) {
    139. pMarker->move(0, ptParent.y());
    140. pMarker->setProperty(
    141. "ICS_MarkerValue",
    142. pMarker->property("ICS_MarkerInverted").toBool()
    143. ? m_fMaximum - float(ptParent.y() - m_nOrigin) * 25.4f / float(physicalDpiY())
    144. : float(ptParent.y() + m_nOrigin) * 25.4f / float(physicalDpiY())
    145. );
    146. }
    147.  
    148. emit markerValueChanged(m_lstMarkers.indexOf(pMarker), pMarker->property("ICS_MarkerValue").toFloat());
    149.  
    150. return true;
    151. }
    152. }
    153.  
    154. break;
    155.  
    156. default:
    157. break;
    158. }
    159.  
    160. return QWidget::eventFilter(pSender, pEvent);
    161. }
    162.  
    163. void ICSRulerWidget::paintEvent(QPaintEvent* pEvent) {
    164. Q_UNUSED(pEvent);
    165.  
    166. QPainter cPainter(this);
    167.  
    168. cPainter.fillRect(0, 0, width(), height(), Qt::white);
    169. cPainter.setPen(Qt::lightGray);
    170. cPainter.drawRect(0, 0, width(), height());
    171.  
    172. if(m_nOrientation == Qt::Horizontal) {
    173. float nX = 8.0f;
    174.  
    175. cPainter.translate(m_nOrigin, 0.0f);
    176.  
    177. for(int nValue = 0; nValue <= m_fMaximum; nValue += 2) {
    178. if(nX + m_nOrigin >= 0 && nX + m_nOrigin < width()) {
    179. if(nValue % 10 == 0) {
    180. auto strText = QString::number(nValue / 10);
    181.  
    182. cPainter.setPen(QPen(QBrush(Qt::black), 2.0f));
    183. cPainter.drawLine(nX, height() - 2, nX, height() - fontMetrics().height() / 2 - 2);
    184. cPainter.drawText(nX - fontMetrics().width(strText) / 2, height() - fontMetrics().height() / 2 - 8, strText);
    185. } else {
    186. cPainter.setPen(Qt::black);
    187. cPainter.drawLine(nX, height() - 2, nX, height() - fontMetrics().height() / 3 - 2);
    188. }
    189. }
    190.  
    191. nX += float(physicalDpiX()) / 12.7f;
    192. }
    193. } else {
    194. float nY = 8.0f;
    195.  
    196. cPainter.translate(0.0f, m_nOrigin);
    197.  
    198. for(int nValue = 0; nValue <= m_fMaximum; nValue += 2) {
    199. if(nY + m_nOrigin >= 0 && nY + m_nOrigin < height()) {
    200. if(nValue % 10 == 0) {
    201. auto strText = QString::number(nValue / 10);
    202.  
    203. cPainter.setPen(QPen(QBrush(Qt::black), 2.0f));
    204. cPainter.drawLine(width() - 2, nY, width() - fontMetrics().height() / 2 - 2, nY);
    205. cPainter.drawText(4, nY + fontMetrics().height() / 3, strText);
    206. } else {
    207. cPainter.setPen(Qt::black);
    208. cPainter.drawLine(width() - 2, nY, width() - fontMetrics().height() / 3 - 2, nY);
    209. }
    210. }
    211.  
    212. nY += float(physicalDpiY()) / 12.7f;
    213. }
    214. }
    215. }
    216.  
    217. void ICSRulerWidget::setOrigin(int pOrigin) {
    218. m_nOrigin = -pOrigin;
    219.  
    220. for(auto pMarker: m_lstMarkers) {
    221. auto fValue = pMarker->property("ICS_MarkerValue").toFloat();
    222.  
    223. if(m_nOrientation == Qt::Horizontal)
    224. pMarker->move(
    225. pMarker->property("ICS_MarkerInverted").toBool()
    226. ? m_nOrigin + float(physicalDpiX()) / 25.4f * (m_fMaximum - fValue)
    227. : m_nOrigin + float(physicalDpiX()) / 25.4f * fValue,
    228. 0
    229. );
    230. else
    231. pMarker->move(
    232. 0,
    233. pMarker->property("ICS_MarkerInverted").toBool()
    234. ? m_nOrigin + float(physicalDpiY()) / 25.4f * (m_fMaximum - fValue)
    235. : m_nOrigin + float(physicalDpiY()) / 25.4f * fValue
    236. );
    237. }
    238.  
    239. update();
    240. }
    241.  
    242. void ICSRulerWidget::setMaximum(float pMaximum) {
    243. if(m_fMaximum != pMaximum) {
    244. m_fMaximum = pMaximum;
    245.  
    246. for(int nIndex = 0; nIndex < m_lstMarkers.size(); nIndex++) {
    247. auto fValue = markerValue(nIndex);
    248.  
    249. setMarkerRange(nIndex, 0, m_fMaximum);
    250.  
    251. if(fValue > pMaximum)
    252. setMarkerValue(nIndex, pMaximum);
    253. else {
    254. if(m_nOrientation == Qt::Horizontal)
    255. m_lstMarkers[nIndex]->move(
    256. m_lstMarkers[nIndex]->property("ICS_MarkerInverted").toBool()
    257. ? m_nOrigin + float(physicalDpiX()) / 25.4f * (m_fMaximum - fValue)
    258. : m_nOrigin + float(physicalDpiX()) / 25.4f * fValue,
    259. 0
    260. );
    261. else
    262. m_lstMarkers[nIndex]->move(
    263. 0,
    264. m_lstMarkers[nIndex]->property("ICS_MarkerInverted").toBool()
    265. ? m_nOrigin + float(physicalDpiY()) / 25.4f * (m_fMaximum - fValue)
    266. : m_nOrigin + float(physicalDpiY()) / 25.4f * fValue
    267. );
    268. }
    269. }
    270.  
    271. update();
    272. }
    273. }
    274.  
    275. void ICSRulerWidget::clearMarkers(void) {
    276. qDeleteAll(m_lstMarkers);
    277. update();
    278. }
    To copy to clipboard, switch view to plain text mode 

    I've attached the icsrulerwidget.h file: icsrulerwidget.h

    The original Thread: http://www.qtcentre.org/threads/6054...implementation

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to create a ruler widget for a qcustomplot with a given ICSRulerWidget Class?

    I think you misunderstand what this widget does. It is not a ruler for measuring the distance between two points on the screen, it is like the bar you see at the top of Microsoft Word and other document editing programs. The picture below is from OpenOffice. I do not know how the ICSRulerWidget looks, but it is probably similar.

    Capture.jpg
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Ruler widget implementation
    By golubevsv in forum Qt-based Software
    Replies: 3
    Last Post: 26th July 2016, 09:21
  2. Ruler implementation
    By brcain in forum Qt Programming
    Replies: 0
    Last Post: 19th November 2015, 20:13
  3. show object (scene) in widget in class class mainwindow
    By rimie23 in forum Qt Programming
    Replies: 8
    Last Post: 1st May 2012, 16:15
  4. Replies: 7
    Last Post: 18th August 2011, 14:43
  5. Replies: 1
    Last Post: 6th May 2010, 11:05

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.