在滚动条上绘制文本

时间:2014-03-24 10:01:42

标签: qt

我想知道是否可以在滚动条中绘制文本。更具体地说,在滚动小部件的“可抓取块”内。
我正在使用PythonQt,因此我无法创建自己的小部件。我只需要使用默认小部件即可。
有什么方法可以在Qt中完全做到这一点吗?

更多我需要的图形表示:

(香草:'X'是'抢'手柄')     -------------------------------------------------- -----
    | ...... XXXXXXXXXXXX ...................................... |
    -------------------------------------------------- -----

(目标)
    -------------------------------------------------- -----
    | ...... XX 自定义文字在这里! XX ....................... |
    -------------------------------------------------- -----

谢谢!

编辑:现在删除了幽闭恐怖的PythonQt要求:)

1 个答案:

答案 0 :(得分:3)

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

您需要执行类似的QScrollBar子类。

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
}

可以从QStyle使用的其他方法确定Slider的确切大小。以下是挖掘一些qt资源的一些信息:

qscrollbar.cpp

摘自Qt来源

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;

希望有所帮助。