Is it possible to add a margin ruler to a QTextEdit



  • I am hoping to write some book writing software based on LSB, which will have word processing capabilities.
    I want to know if it is possible to put a ruler on a QTextEdit which can also be used to change the margin.
    Either in a QTextEdit windows or above it joined, like in the image below.

    I know how to do all the buttons now, but don't know how to add the ruler.

    image



  • Well I have got something which resembles what I am after, by using the slider with ticks.
    ruler

    So this is close to what I want, but the problem is with the slider there is only one pointer. I need two pointers for both margins.

    It would be nice if some of the ticks were longer at intervals as well.

    So based on my first question. How do I add two pointers to a Qslider and is it possible to have longer and shorter ticks?


  • Lifetime Qt Champion

    Hi,

    You should write your own slider then based on QAbstractSlider, doing so you can render the ticks the way you want them.



  • @SGaist
    I kinda came to this conclusion, but I am having trouble finding a tutorial on building a custom widget.
    So I don't really know where to start. Will let you know if I can work it out.

    Wouldn't it be good if there was a page where you could get custom widgets that other people have made.


  • Lifetime Qt Champion



  • @SGaist
    Yes exactly like that.

    I just followed a tutorial on making a custom widget. It showed how to inherit QWidget and the use QPainter to over ride the Widget. eg

    void pieChartWidget::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QRectF size = QRectF(10,10, this->width()-10, this->width()-10);
        painter.setBrush(Qt::red);
        painter.drawPie(size, 0 , 90*16);
        painter.setBrush(Qt::blue);
        painter.drawPie(size,90*16,270*16);
    }
    

    I presume to make a custom slider I have to inherit the QAbstractSlider and then over-ride the paint event the same way. Right I am going to try something like this now LOL.



  • Ok I tried writing a class to inherit the QAbstractSlider, but it didn't work, so instead I tried to inherit the QSlider, which seemed to compile ok, and I wrote the following code, hoping something would turn red.
    The problem is this. With the tutorial I watched for making a pie chart you have to promote your widget to use your own code. It worked with the pie chart, but when I try to promote my QSlider the promote button stays greyed out and it won't let me promote. However this is the code I tried.

    #include "doublehandleslider.h"
    
    #include <QPainter>
    
    doubleHandleSlider::doubleHandleSlider(QWidget *parent) : QSlider(parent)
    {
    
    }
    
    void doubleHandleSlider::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QRectF size = QRectF(10,10, this->width()-10, this->width()-10);
        painter.setBrush(Qt::red);
    
    }
    

    I am not even sure if the code would have turned my QSlider red. I don't really want it red, but if it changed I knew I would be getting somewhere. However I can't promote my QSlider to use my own code yet.

    I am probably doing everything wrong, because I am trying to pick stuff up from tutorials.



  • Ok I have managed to get the QAbstractSlider to compile now, but nothing is showing.
    Here is my h file

    #ifndef DOUBLEHANDLESLIDER_H
    #define DOUBLEHANDLESLIDER_H
    
    #include <QAbstractSlider>
    
    class doubleHandleSlider : public QAbstractSlider
    {
    
    public:
        explicit doubleHandleSlider(QWidget *parent = 0);
    
    protected:
        void paintEvent(QPaintEvent *);
    
    };
    
    #endif // DOUBLEHANDLESLIDER_H
    
    

    and here is my cpp file

    #include "doublehandleslider.h"
    
    #include <QPainter>
    
    doubleHandleSlider::doubleHandleSlider(QWidget *parent) : QAbstractSlider(parent)
    {
    
    }
    
    void doubleHandleSlider::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QRectF size = QRectF(10,10, this->width()-10, this->width()-10);
        painter.setBrush(Qt::red);
    
    }
    

    I am putting an empty widget into the gui, and then promoting to my class. Now the good thing is that everything runs without errors. The bad thing I don't see anything.

    So I think I am doing it correctly, but probably not the putting the correct commands into the painter.
    All I want to know is if I am going in the right direction with this, or if I am totally off the mark.

    PS.
    I have just made a series of lines like this

    void doubleHandleSlider::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setBrush(Qt::red);
    
        for ( int a=20; a<200; a=a+5) {
            painter.drawLine(a,10,a,20);
        }
    }
    

    I am not sure. Also I am not sure how to put the Handle on to the slider yet. I am pleased I got something to show, at least, but I don't know how to make my lines resize if the widget is resized. What I don't understand is why my lines are black and not red.


  • Qt Champions 2016

    @Asimov
    Hi
    Good work. Seems on right track.
    You lines are not red as lines use the QPen and not QBrush. :)



  • @mrjj
    Yes I worked it out in the end.

     QPainter painter(this);
        QPen pen;
        pen.setColor(Qt::red);
        painter.setPen(pen);
    

    Although I still haven't worked out how to put the two handles on the slider yet.
    By the way I don't really want it red, but just trying to work out how to do stuff.

    The other thing is that if I put my custom widget above the QTextEdit windows, and use the layout controls it covers up my custom widget for some reason.

    I want the widget to resize when I resize my QTextEdit it is above you see.

    Still got a lot to learn, and stealing bits from tutorials I have been watching heh heh.


  • Qt Champions 2016

    @Asimov
    Super.
    Hmm if you use a layout it should not cover it. are you sure u insert BOTH into the layout?

    You could go and look at the source for the slider. to see how it works.


  • Lifetime Qt Champion

    Just in case the libqxt provides a span slider that might be of interest.



  • @SGaist
    I did look at libqxt but didn't really want an external library. Also it said on that page that it was no longer being developed.

    So I have been a few days researching this and I have made some progress. I have now two colour ticks, but I have no idea how about making them relate to inches or whatever as yet, as I have a bigger problem. I don't know how to move the handles I have created. Also I don't know if there is a way to change the width of the handles either.
    thing

    I presume to move the handles I have to use some mouse event or something, but I don't know how to do that. I suppose I could reference the handles in my header file so I have access to them in a mouse event function, but I haven't got a clue as of yet.
    Anyway here is my code so far. Originally I used a QStylePainter, but then I changed it to a QPainter as I could do the handles and the lines in that. I like the fact I am drawing the handles behind the ticks so that you can see through them.

    Now all I gotta do is work out how to move them, and then make an accurate measure for possible printing and setting the margins.

    void doubleHandleSlider::paintEvent(QPaintEvent *)
    {
    
        QPainter painter(this);
    
        painter.fillRect(rect(), Qt::white);
    
        QStyleOptionSlider option;
        option.init(this);
        option.orientation = Qt::Horizontal;
        option.minimum = 0;
        option.maximum = 100;
    
        option.sliderPosition = 0;
        option.sliderValue = 20;
        option.subControls = QStyle::SC_SliderHandle;
        style()->drawComplexControl(QStyle::CC_Slider,&option,&painter);
    
        option.sliderPosition = 100;
        option.sliderValue = 80;
        style()->drawComplexControl(QStyle::CC_Slider,&option,&painter);
    
        QPen pen;
        pen.setColor(Qt::red);
        painter.setPen(pen);
        int height=7;
    
        int counter=0;
        for ( int a=0; a<this->width(); a=a+8) {
            if(counter==0){
                pen.setColor(Qt::red);
                 height=7;
            }else{
                pen.setColor(Qt::black);
                height=5;
            }
            painter.setPen(pen);
            painter.drawLine(a,0,a,height);
            counter++;
            if(counter==6) counter=0;
        }
    }
    


  • http://doc.qt.io/qt-5/qml-qtquick-mousearea.html should help you with your mouse interactions.

    Maybe use a mouse area and containsPress ?

    Hopefully enough to get you moving again.


  • Lifetime Qt Champion

    I was only suggesting to take a look at the implementation not to integrate libqxt in your project. The wiki page also suggests to take the classes of interest into your project rather than try to build the whole library.



  • I have to be honest I have been many days researching how to do this, and I am still stuck even with the documentation that 6thC posted. I am getting a little disheartened at the moment.

    There isn't many examples how to make a qslider from scratch, and even the ones out there seem very complex.
    I have got the measure to work and even put handles on, but I can't seem to get them to move.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.