Results 1 to 4 of 4

Thread: Editable QLCDNumber

  1. #1
    Join Date
    Jun 2013
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question Editable QLCDNumber

    Hi guys

    I'd like to hear you suggestions to the following problem.

    I need an editable lcd editor in my GUI. I mean that I display some value in it and allow a user to edit it in a clickable way. For example, the current value is 123. A user clicks to the area of digit 2 and press some digit key on his keyboard to modify this digit.

    The quick solution spinning in my mind is to implement a QButton over the QLCDNumber widget but it seems to be a dirty hack.

    Are there any tested solutions for this case? If anyone could share an example I'd be highly appreciated. But anyhow I need a concept to start.

    My environment : Qt4.7, no QML.

    BR,
    Dmitry

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Editable QLCDNumber

    Subclass QLCDNumber, activate focus and reimplement key events.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jun 2013
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Editable QLCDNumber

    Thx for the idea.
    Could you please clarify the following items:
    1. "activate focus" - do you mean setFocus() method?
    2. "reimplement key events" -ok, this is quite clear. But how do I know the exact item position to be edited? I guess I should somehow track the mouse position and the desired digit position of the LCD, right? If yes, then what is the way to get the LCD item position?


    Added after 1 20 minutes:


    and
    3. What is the right wat to highlight the "editable" item of the current LCD value?
    Inside Qt help I see the following note : "It is not possible to retrieve the contents of a QLCDNumber object, although you can retrieve the numeric value with value()". Therefore my question : is it possible to find a solution based on QLCDNumber?
    Last edited by QDmitry; 26th June 2013 at 14:42.

  4. #4
    Join Date
    Jun 2013
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Editable QLCDNumber

    Ok, so here is my solution to this topic.
    ==============================
    qeditablelcd.h
    ==============================
    #ifndef QEDITABLELCD_H
    #define QEDITABLELCD_H

    #include <QLCDNumber>
    #include <QPaintEvent>
    #include <QKeyEvent>
    #include <QRectF>
    #include <QWheelEvent>

    class qeditablelcd : public QLCDNumber
    {
    Q_OBJECT
    public:
    explicit qeditablelcd(QObject *parent = 0);

    signals:

    public slots:

    protected :
    void mousePressEvent ( QMouseEvent * e );
    void keyPressEvent ( QKeyEvent * event );
    void paintEvent( QPaintEvent * e );
    void wheelEvent ( QWheelEvent * event );

    private :
    void setDigitAreaPressed( QMouseEvent * e, const int areaId = -1 );
    void positionValueIncrement( const int numSteps );
    QRectF mDigitRect;
    int mDigitIdToChange;
    };

    #endif // QEDITABLELCD_H

    ======================
    qeditablelcd.cpp
    ======================
    #include <QMouseEvent>
    #include <QBrush>
    #include <QPainter>
    #include <QString>
    #include <QtCore/qmath.h>

    #include "qeditablelcd.h"

    qeditablelcd::qeditablelcd(QObject *parent) :
    QLCDNumber()
    {
    /* Mouse selected digit item Id */
    this->mDigitIdToChange = -1;
    this->setFocusPolicy(Qt::ClickFocus);
    }

    void qeditablelcd::setDigitAreaPressed( QMouseEvent * e, const int areaId )
    {
    int ndigits = this->digitCount();
    int digitSpace = this->smallDecimalPoint() ? 2 : 1;
    int xSegLen = this->width()*5/(ndigits*(5 + digitSpace) + digitSpace);
    int ySegLen = this->height()*5/12;
    int segLen = ySegLen > xSegLen ? xSegLen : ySegLen;
    int xAdvance = segLen*( 5 + digitSpace )/5;
    int xOffset = ( this->width() - ndigits*xAdvance + segLen/5 )/2;

    /* Use the predefined Id if necessary */
    if ( areaId != -1 ) {
    this->mDigitRect.setRect(xOffset + xAdvance*areaId, this->y(), xAdvance, this->height() );
    return;
    }

    int xPos = e->pos().x();
    int itemId = -1;

    for ( int i = 0; i < ndigits; i++ ) {
    if ((xPos >= xOffset + xAdvance*i) && (xPos < xOffset + xAdvance*(i + 1))) {
    itemId = i;
    this->mDigitRect.setRect(xOffset + xAdvance*itemId, this->y(), xAdvance, this->height() );
    break;
    }
    }

    this->mDigitIdToChange = itemId;
    }

    void qeditablelcd::mousePressEvent ( QMouseEvent * e )
    {
    this->setDigitAreaPressed(e);
    update();
    }

    void qeditablelcd:aintEvent(QPaintEvent * e)
    {
    /* If are not selected - nothing to draw except lcdnumber itself */
    /* Though never occured while testing */
    if (!( this->mDigitIdToChange == -1 )) {
    QPainter Painter(this);
    Painter.setBrush(QBrush(Qt::black, Qt:ense7Pattern));
    Painter.drawRect(this->mDigitRect);
    }
    QLCDNumber:aintEvent(e);
    }

    void qeditablelcd::keyPressEvent ( QKeyEvent * event )
    {
    int key = event->key();

    /* Filter out all non digit keys */
    if (( key >= Qt::Key_0 ) && ( key <= Qt::Key_9 )) {
    if ( this->mDigitIdToChange != -1 ) {
    /* Convert double value to a string representation */
    QString lcdStr;
    lcdStr.setNum(int(this->value()));

    /* Insert starting zeros in lcdStr representation */
    int l = this->digitCount() - lcdStr.length();
    for (int i = 0; i < l; i++) {
    lcdStr.insert(0,"0");
    }

    /* Convert key value to string representation */
    QString keyVal;
    keyVal.setNum( key - Qt::Key_0 );

    /* Replace selected digit with the desired one */
    lcdStr.replace(this->mDigitIdToChange, 1, keyVal);

    /* Update lcdnumber */
    this->display(lcdStr.toDouble());

    /* Switch to the next digit item */
    if ( this->mDigitIdToChange == this->digitCount() - 1 ) {
    this->mDigitIdToChange = 0;
    } else {
    this->mDigitIdToChange++;
    }

    this->setDigitAreaPressed(NULL, this->mDigitIdToChange);
    update();
    }
    }

    /* Enter + Esc press event handler */
    if (( key == Qt::Key_Return ) || ( key == Qt::Key_Escape )) {
    this->mDigitIdToChange = -1;
    update();
    }

    }

    void qeditablelcd::wheelEvent ( QWheelEvent * event )
    {
    if ( this->mDigitIdToChange != -1 ) {
    /* Number of steps within a single event = delta() / (15*8) */
    this->positionValueIncrement(event->delta()/(15*8));
    }
    }

    void qeditablelcd:ositionValueIncrement( const int numSteps )
    {
    /* Multiply rate */
    qreal multiplyer = qPow( 10, this->digitCount() - 1 - this->mDigitIdToChange );

    this->display(this->value() + numSteps*multiplyer );
    }

Similar Threads

  1. Modelling a QLCDNumber in QML
    By lixo1 in forum Qt Quick
    Replies: 1
    Last Post: 24th August 2011, 14:19
  2. QLCDNumber problem
    By ale301168 in forum Newbie
    Replies: 1
    Last Post: 11th November 2009, 21:16
  3. QLCDNumber display
    By jhearon in forum Qt Programming
    Replies: 0
    Last Post: 26th October 2008, 23:53
  4. QLCDNumber justify
    By davisjamesf in forum Qt Programming
    Replies: 1
    Last Post: 5th July 2007, 10:02
  5. QLabel and QLCDNumber
    By mickey in forum Newbie
    Replies: 5
    Last Post: 17th March 2006, 08:12

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.