c++ - 在鼠标悬停在填充栏上时更改 QProgressBar 的颜色/文本

标签 c++ qt

如果鼠标悬停在栏的填充部分上方,如何更改 QProgressBar 的颜色和/或文本(格式)?

我将多个 QProgressBar 堆叠在一起,每个显示的内容都比前一个多。

我想在鼠标悬停时突出显示仍在鼠标下方的最大栏,并显示一些特定于栏的文本。但是,条形图的大小相同,因此我想识别条形图的填充区域。

image

例如,如果鼠标悬停在第三个栏上,我想突出显示从左侧到第三个栏的部分,并显示特定于第三个栏的文本。

这是我用于堆叠 ProgressBars 的代码:

class MultiProgressBar : public QWidget
{
    Q_OBJECT
public:
    MultiProgressBar( QWidget* parent = Q_NULLPTR ) : QWidget( parent ), layout( new QStackedLayout( this ) )
    {
        layout->setMargin( 0 );
        layout->setStackingMode( QStackedLayout::StackAll );
    }

    void insertBar( QColor const& color )
    {
        auto bar = new QProgressBar();
        bar->setTextVisible( false );
        bar->setRange( 0, 10000 );

        QPalette palette = this->palette();
        palette.setColor( QPalette::Highlight, QColor( color.red(), color.green(), color.blue(), 100 ) );
        palette.setColor( QPalette::Base, QColor( color.red(), color.green(), color.blue(), 0 ) );
        bar->setPalette( palette );

        layout->addWidget( bar );
        progress_bars.push_back( bar );
    }

public slots:
    void setValues( const std::vector< int >& values, const std::vector< std::string >& names )
    {
        if ( values.size() < progress_bars.size() )
        {
            for ( auto* widget : progress_bars )
            {
                layout->removeWidget( widget );
            }
            progress_bars.clear();
        }
        while ( progress_bars.size() < values.size() )
        {
            insertBar( QColor( 0x46, 0xA1, 0xD9, 255 ) );
        }

        for ( auto i = 0; i < progress_bars.size(); ++i )
        {
            progress_bars[ i ]->setValue( values[ i ] );
            // progress_bars[ i ]->setFormat( QString::fromStdString( names[ i ] ) );
        }
    }

private:
    std::vector< QProgressBar* > progress_bars;
    QStackedLayout* layout;
};

最佳答案

1) 要更改填充区域的颜色,您可以像这样为进度条的调色板设置新颜色:

QPalette newPalette = bar.palette();
newPalette.setColor(QPalette::Highlight, "red"); // setting color to red
bar.setPalette(newPalette);

2.1) 可以使用 void setFormat(const QString &format); 函数将文本分配给进度条,就像在注释字符串中一样

progress_bars[ i ]->setFormat( QString::fromStdString( names[ i ] ) );

2.2) 通过调用QProgressBar::text() 函数获取文本;

3) 如果你想突出显示特定的进度条,你可以重新实现

QWidget::mouseMoveEvent(QMouseEvent *event);

您可以在其中计算填充区域的边距:

void mouseMoveEvent(QMouseEvent *e){
    highlightProgressBars(e->pos()); // passing position of mouse cursor
}

注意:不要忘记为进度条和您的 MultiProgressBar 小部件启用鼠标跟踪:

bar->setMouseTracking(true);

4) 下面的函数获取鼠标在参数中的位置。它突出显示从左侧到指向的进度条的区域,并在控制台中显示通过 format 属性分配给突出显示的进度条的文本

void highlightProgressBars(QPoint point){
    int widthOfBar = ((QProgressBar*)progress_bars.at(0))->width();
    int valueForPoint = 10000 / widthOfBar; // value of progressbar for width==1
    for (auto pb = this->progress_bars.begin(); pb != this->progress_bars.end(); ++pb) { // iterating vector to paint progressbars
        int leftMargin = 0; // "left margin" of current progressbar is in fact right margin of filled area of previous progressbar
        if(pb != this->progress_bars.begin()){ // except first progressbar in vector which doesn't have previous progressbar
            --pb; // get previous progressbar
            leftMargin = ((QProgressBar*)*pb)->value() / valueForPoint; // get width of filled area
            ++pb; // return to current progressbar
        }

        if(leftMargin < point.x()) { // if position of cursor is to the right of "left margin" of current progressbar we highlight it
            QPalette newPal = ((QProgressBar*)*pb)->palette();  //getting palette
            newPal.setColor(QPalette::Highlight,"red"); // and setting color of filled area
            ((QProgressBar*)*pb)->setPalette(newPal); // finally setting palette to widget
            qDebug() << ((QProgressBar*)*pb)->text(); // show text of highlighted progressbar in console
        }
        else{ // if not we highlight it another way
            QPalette newPal = ((QProgressBar*)*pb)->palette();
            newPal.setColor(QPalette::Highlight,"lightblue");
            ((QProgressBar*)*pb)->setPalette(newPal);
        }

    }
}

如果你只想突出显示一个进度条,你应该更改上面的代码:

if(leftMargin < point.x()) {

到:

int rightMargin = ((QProgressBar*)*pb)->value() / valueForPoint;
if(leftMargin < point.x() && point.x() < rightMargin) {

关于c++ - 在鼠标悬停在填充栏上时更改 QProgressBar 的颜色/文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39792055/

相关文章:

C++ new 运算符和错误检查

c++ - Qt - 如何将多个 QGroupBox 添加到 QTabWidget?

c++ - 为什么 QTcpSocket 不写?我需要刷新它才能发送我的数据

c++ - 扩展QMessageBox类时如何访问QMessageBoxPrivate中的label变量?

c++ - 将 Median Cut 减色算法的输出调色板应用于源图像

c++ - C++中成员函数的内存分配

c++ - 以列表作为值初始化 map

c++ - MFC BitBlt 和 SetDIBits 与 SetBitmapBits

C++ 程序读取 '*' 为 'a'

c++ - QMediaPlayer 在 dll 中不工作