具有重叠子小部件的 Qt 自定义小部件

Posted

技术标签:

【中文标题】具有重叠子小部件的 Qt 自定义小部件【英文标题】:Qt Custom widget with overlapping subwidgets 【发布时间】:2014-11-11 03:09:15 【问题描述】:

我正在尝试在 Qt5 中制作一个自定义小部件,它有点像 QProgressBar,但有 3 个滑块和用户可移动:(略微损坏的 JS 实现:codepen、gist)

我在弄清楚如何做到这一点时遇到了问题。我的尝试未能正确呈现小部件的所有部分(使得选择和移动它的不同部分变得非常困难)或无法与 VBoxLayout 正常工作(不扩展以适应水平空间)

我最近的尝试(你应该可以从构造函数中得到大致的想法,没有其他的实现)

UTrackSlider::UTrackSlider(QWidget *parent) : QWidget(parent)

    this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);

    // CIRCLE_HEIGHT = 10
    // BACKGROUND_HEIGHT = 30

    /// @todo css should be in global stylesheet
    background = new QLabel(this);
    background->setMinimumHeight(this->BACKGROUND_HEIGHT);
    background->setStyleSheet("QLabel border: 1px solid gray; background-color:white; border-radius:2px");
    background->setAttribute(Qt::WA_DeleteOnClose);

    cue = new QLabel(this);
    cue->setFixedSize(QSize(this->CIRCLE_HEIGHT, this->CIRCLE_HEIGHT));
    cue->setStyleSheet("QLabel:hover border: 2px solid #d9534f; border-radius:5px");
    cue->setAttribute(Qt::WA_DeleteOnClose);

    duration = new QLabel(this);
    duration->setFixedSize(3, this->BACKGROUND_HEIGHT);
    duration->setStyleSheet("QLabelborder: 3px solid #2376bb QLabel:hoverborder: 5px solid #2376bb");
    duration->setAttribute(Qt::WA_DeleteOnClose);

    intro = new QLabel(this);
    intro->setFixedSize(QSize(this->CIRCLE_HEIGHT, this->CIRCLE_HEIGHT));
    intro->setStyleSheet("QLabel:hover border: 2px solid #5bc85c; border-radius:5px");
    intro->setAttribute(Qt::WA_DeleteOnClose);

    QGridLayout *mainLayout = new QGridLayout(this);
    mainLayout->addWidget(cue, 5, 0);
    mainLayout->addWidget(background, 0, this->CIRCLE_HEIGHT);
    mainLayout->addWidget(duration, 2, this->CIRCLE_HEIGHT);
    mainLayout->addWidget(intro, 5, this->CIRCLE_HEIGHT + this->BACKGROUND_HEIGHT);
    this->setLayout(mainLayout);

基本上,关于我应该如何构造这个复合小部件以使其在所有这些条件下工作的任何指针?

编辑:在与#qt 上的某些人讨论该问题后,我得出结论,我必须重写paintEvent。但这也意味着重写一些其他函数来实现点击和拖动效果,我不知道从哪里开始

【问题讨论】:

【参考方案1】:

你是对的,你必须重新实现

1.void paintEvent(QPaintEvent *) 
2.void mouseMoveEvent(QMouseEvent *)
3.void mousePressEvent(QMouseEvent *)
4.void mouseReleaseEvent(QMouseEvent *)

QWidget。

为了正确处理鼠标事件,您可以使用QCoreApplication::sendEvent(QObject *, QEvent *) 将事件传递给目标小部件。

这是一个例子: https://github.com/Serge45/MultiSlider

在本例中,我在一个容器小部件中创建了三个小部件(ColorSlider),然后使用链表正确传播鼠标事件。

【讨论】:

哇。你是为我做的吗?是的!非常感谢:)

以上是关于具有重叠子小部件的 Qt 自定义小部件的主要内容,如果未能解决你的问题,请参考以下文章

Qt 缩放/缩放 QFrame 的内容(小部件等)

将自定义 QEvent 传播到 Qt/PyQt 中的父小部件

使用我的 QT5 自定义小部件调整 QGroupBox 大小

使用 PyQt5 在 Qt Designer 中的自定义(升级)小部件中获取另一个小部件的当前值

Qt 中自定义小部件的自定义样式

如何开始使用自定义 GUI 小部件