Draw text on scrollbar

后端 未结 1 1207
说谎
说谎 2020-12-17 02:27

I was wondering if it was possible to draw text inside a scrollbar. More specifically, inside the \"grab-able block\" of the scroll widget.
I\'m using PythonQt,

相关标签:
1条回答
  • 2020-12-17 02:57

    http://www.qtcentre.org/threads/15032-QScrollBar-subclass-constructor-ignores-orientation-Qt4-4

    You will want to do a similar QScrollBar subclass.

    mainwindow.cpp

    #include "mainwindow.h"
    #include <QScrollArea>
    #include "scrollbar.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        QScrollArea * sa = new QScrollArea;
    
        sa->setVerticalScrollBar(new ScrollBar(Qt::Vertical));
        sa->setHorizontalScrollBar(new ScrollBar(Qt::Horizontal));
        QWidget *w = new QWidget;
        sa->setWidget(w);
    
        w->setFixedSize(1000, 1000);
        this->setCentralWidget(sa);
    }
    

    scrollbar.h

    #ifndef SCROLLBAR_H
    #define SCROLLBAR_H
    
    #include <QScrollBar>
    #include <QPaintEvent>
    
    class ScrollBar : public QScrollBar
    {
        Q_OBJECT
    public:
        ScrollBar ( Qt::Orientation orientation, QWidget * parent = 0 );
    public slots:
    
    signals:
    
    protected:
        void paintEvent(QPaintEvent* event);
    };
    
    #endif // SCROLLBAR_H
    

    scrollbar.cpp

    #include "scrollbar.h"
    #include <QPainter>
    
    double map(double x1, double x, double x2, double y1, double y2)
    {
        return y1 + (y2 -y1)*(x - x1)/(x2 - x1);
    }
    
    ScrollBar::ScrollBar( Qt::Orientation orientation, QWidget * parent ): 
        QScrollBar (orientation, parent)
    {
    
    }
    
    void ScrollBar::paintEvent(QPaintEvent * event)
    {
        int x, y, w, h;
        this->rect().getRect(&x,&y,&w,&h);
        // This calls the base class's paint calls
        QScrollBar::paintEvent(event);
        // The following is painted on top of it
        QPainter p(this);
        p.setPen(QPen(Qt::red,1));
        if(this->orientation() == Qt::Horizontal)
        {
            // It is difficult to inspect the size of the slider out of the qscrollbar
            // and its position.  This draws a red box that moves with the slider pos
            int delta = map(this->minimum(), this->sliderPosition(), 
                            this->maximum(), 0, this->width()*3/4);
            p.drawRect(sliderPosition(),y,width()/4,h);
        }
        else
        {
            int delta = map(this->minimum(), this->sliderPosition(), 
                            this->maximum(), 0, this->height()*3/4);
            p.drawRect(x,sliderPosition(),w,height()/4);
        }
        // Then draw text inside with p.drawText
    }
    

    Determining the exact size of the Slider might be possible from other methods that are used by QStyle. Here is some information from digging through some of the qt sources:

    qscrollbar.cpp

    Excerpts from the Qt Sources

    void QScrollBar::paintEvent(QPaintEvent *)
    {
        Q_D(QScrollBar);
        QPainter p(this);
        QStyleOptionSlider opt;
        initStyleOption(&opt);
        opt.subControls = QStyle::SC_All;
        if (d->pressedControl) {
            opt.activeSubControls = (QStyle::SubControl)d->pressedControl;
            if (!d->pointerOutsidePressedControl)
                opt.state |= QStyle::State_Sunken;
        } else {
            opt.activeSubControls = (QStyle::SubControl)d->hoverControl;
        }
        style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p, this);
    }
    

    qcommonstyle.cpp

     // From style()->drawComplexControl(QStyle::CC_ScrollBar
    if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
        // Make a copy here and reset it for each primitive.
        QStyleOptionSlider newScrollbar = *scrollbar;
        State saveFlags = scrollbar->state;
    
        if (scrollbar->subControls & SC_ScrollBarSubLine) {
            newScrollbar.state = saveFlags;
            newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubLine, widget);
            if (newScrollbar.rect.isValid()) {
                if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine))
                    newScrollbar.state &= ~(State_Sunken | State_MouseOver);
                proxy()->drawControl(CE_ScrollBarSubLine, &newScrollbar, p, widget);
            }
        }
        if (scrollbar->subControls & SC_ScrollBarAddLine) {
            newScrollbar.rect = scrollbar->rect;
            newScrollbar.state = saveFlags;
            newScrollbar.rect = proxy()->a (cc, &newScrollbar, SC_ScrollBarAddLine, widget);
            if (newScrollbar.rect.isValid()) {
                if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine))
                    newScrollbar.state &= ~(State_Sunken | State_MouseOver);
                proxy()->drawControl(CE_ScrollBarAddLine, &newScrollbar, p, widget);
            }
        }
        if (scrollbar->subControls & SC_ScrollBarSubPage) {
            newScrollbar.rect = scrollbar->rect;
            newScrollbar.state = saveFlags;
            newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSubPage, widget);
            if (newScrollbar.rect.isValid()) {
                if (!(scrollbar->activeSubControls & SC_ScrollBarSubPage))
                    newScrollbar.state &= ~(State_Sunken | State_MouseOver);
                proxy()->drawControl(CE_ScrollBarSubPage, &newScrollbar, p, widget);
            }
        }
        if (scrollbar->subControls & SC_ScrollBarAddPage) {
            newScrollbar.rect = scrollbar->rect;
            newScrollbar.state = saveFlags;
            newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarAddPage, widget);
            if (newScrollbar.rect.isValid()) {
                if (!(scrollbar->activeSubControls & SC_ScrollBarAddPage))
                    newScrollbar.state &= ~(State_Sunken | State_MouseOver);
                proxy()->drawControl(CE_ScrollBarAddPage, &newScrollbar, p, widget);
            }
        }
        if (scrollbar->subControls & SC_ScrollBarFirst) {
            newScrollbar.rect = scrollbar->rect;
            newScrollbar.state = saveFlags;
            newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarFirst, widget);
            if (newScrollbar.rect.isValid()) {
                if (!(scrollbar->activeSubControls & SC_ScrollBarFirst))
                    newScrollbar.state &= ~(State_Sunken | State_MouseOver);
                proxy()->drawControl(CE_ScrollBarFirst, &newScrollbar, p, widget);
            }
        }
        if (scrollbar->subControls & SC_ScrollBarLast) {
            newScrollbar.rect = scrollbar->rect;
            newScrollbar.state = saveFlags;
            newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarLast, widget);
            if (newScrollbar.rect.isValid()) {
                if (!(scrollbar->activeSubControls & SC_ScrollBarLast))
                    newScrollbar.state &= ~(State_Sunken | State_MouseOver);
                proxy()->drawControl(CE_ScrollBarLast, &newScrollbar, p, widget);
            }
        }
        if (scrollbar->subControls & SC_ScrollBarSlider) {
            newScrollbar.rect = scrollbar->rect;
            newScrollbar.state = saveFlags;
            newScrollbar.rect = proxy()->subControlRect(cc, &newScrollbar, SC_ScrollBarSlider, widget);
            if (newScrollbar.rect.isValid()) {
                if (!(scrollbar->activeSubControls & SC_ScrollBarSlider))
                    newScrollbar.state &= ~(State_Sunken | State_MouseOver);
                proxy()->drawControl(CE_ScrollBarSlider, &newScrollbar, p, widget);
    
                if (scrollbar->state & State_HasFocus) {
                    QStyleOptionFocusRect fropt;
                    fropt.QStyleOption::operator=(newScrollbar);
                    fropt.rect.setRect(newScrollbar.rect.x() + 2, newScrollbar.rect.y() + 2,
                                       newScrollbar.rect.width() - 5,
                                       newScrollbar.rect.height() - 5);
                    proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
                }
            }
        }
    }
    break;
    

    Hope that helps.

    0 讨论(0)
提交回复
热议问题