QT 中的自定义外观 svg GUI 小部件,性能非常差

发布于 2024-12-06 19:19:54 字数 10436 浏览 0 评论 0原文

所以我正在尝试为吉他效果程序制作一个图形用户界面。目标之一是允许其他人设计 svg“皮肤”来定制外观。我制作了继承每个小部件(即 qdial)的小部件,并在初始化程序中将皮肤指定的 svg 文件加载到 qGraphicsSvgItem 中。这被放入场景和视图中,并且我适当地重载了调整大小和重新绘制。这有效。

当我将几个自定义 svg 小部件(5 个刻度盘、一个按钮和一个 LED)加载到父小部件中时,CPU 导轨和我的程序冻结。我的处理方式完全错误吗?我应该使用 QT 吗?这似乎比尝试使用样式表完成所有事情更容易(尤其是我不知道如何更改表盘外观)。将小部件保留为 qGraphicsSvgItems 并将它们全部放入父小部件的场景和视图中会改善情况吗?

这是一个实时信号处理程序,所以我不想在 GUI 中消耗大量的 cpu。我尝试对其进行一些研究,但找不到很多关于 svg 的信息。我在 qtCreator 中也没有看到任何性能检查器,或者我会尝试看看瓶颈是什么。不管怎样,在我花更多时间尝试做错误的事情之前,我真的很感激你能提供的任何建议。

非常感谢! _ssj71

附注 这是一些代码(希望足够了) 一个 svg 小部件:

#ifndef QSVGDIAL_H
#define QSVGDIAL_H

#include <QWidget>
#include <QDial>
#include <QtSvg/QSvgRenderer>
#include <QtSvg/QGraphicsSvgItem>
#include <QGraphicsView>
#include <QGraphicsScene>

class qSVGDial : public QDial
{
    Q_OBJECT

public:
    explicit qSVGDial(QWidget *parent = 0);
    explicit qSVGDial(QString knobFile = "defaultKnob.svg", QString needleFile = "defaultNeedle.svg", QWidget *parent = 0);
    ~qSVGDial();

private:
    void paintEvent(QPaintEvent *pe);
    void resizeEvent(QResizeEvent *re);
    float degPerPos;
    float middle;
    float mysize;
    QGraphicsView view;
    QGraphicsScene scene;
    QGraphicsSvgItem *knob;
    QGraphicsSvgItem *needle;
    QSize k,n;

};

#endif // QSVGDIAL_H

cpp:

#include "qsvgdial.h"
#include "math.h"

qSVGDial::qSVGDial(QWidget *parent) :
    QDial(parent)
{
    knob = new QGraphicsSvgItem("defaultKnob.svg");
    needle = new QGraphicsSvgItem("defaultNeedle.svg");
    view.setStyleSheet("background: transparent; border: none");

    k = knob->renderer()->defaultSize();
    n = needle->renderer()->defaultSize();
    needle->setTransformOriginPoint(n.width()/2,n.height()/2);
    knob->setTransformOriginPoint(k.width()/2,k.height()/2);
    degPerPos = 340/(this->maximum() - this->minimum());
    middle = (this->maximum() - this->minimum())/2;
    mysize = k.width();
    if (mysize<n.width())  mysize = n.width();
    if (mysize<k.height()) mysize = k.height();
    if (mysize<n.height()) mysize = n.height();
    mysize = sqrt(2)*mysize;
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    scene.addItem(knob);
    scene.addItem(needle);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}

qSVGDial::qSVGDial(QString knobFile, QString needleFile, QWidget *parent) :
    QDial(parent)
{
    knob = new QGraphicsSvgItem(knobFile);
    needle = new QGraphicsSvgItem(needleFile);
    view.setStyleSheet("background: transparent; border: none");
    k = knob->renderer()->defaultSize();
    n = needle->renderer()->defaultSize();
    needle->setTransformOriginPoint(n.width()/2,n.height()/2);
    knob->setTransformOriginPoint(k.width()/2,k.height()/2);
    if (k!=n)
        needle->setPos((k.width()-n.width())/2,(k.height()-n.height())/2);

    degPerPos = 340/(this->maximum() - this->minimum());
    middle = (this->maximum() - this->minimum())/2;
    mysize = k.width();
    if (mysize<n.width())  mysize = n.width();
    if (mysize<k.height()) mysize = k.height();
    if (mysize<n.height()) mysize = n.height();
    mysize = sqrt(2)*mysize;
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scene.addItem(knob);
    scene.addItem(needle);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}

qSVGDial::~qSVGDial()
{
    //delete ui;

}

void qSVGDial::paintEvent(QPaintEvent *pe)
{
   needle->setRotation((this->sliderPosition() - middle)*degPerPos);
}

void qSVGDial::resizeEvent(QResizeEvent *re)
{
    if (this->width()>this->height())
    {
        view.setFixedSize(this->height(),this->height());
        view.move((this->width()-this->height())/2,0);
        knob->setScale(this->height()/mysize);
        needle->setScale(this->height()/mysize);
        view.centerOn(knob);
    }
    else
    {
        view.setFixedSize(this->width(),this->width());
        view.move(0,(this->height()-this->width())/2);
        knob->setScale(this->width()/mysize);
        needle->setScale(this->width()/mysize);
        view.centerOn(knob);
    }
    QDial::resizeEvent(re);
}

父标头:

#ifndef PEDAL_H
#define PEDAL_H

#include <QtGui/QWidget>
#include <QString>
#include <QtSvg/QSvgRenderer>
#include <QtSvg/QGraphicsSvgItem>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <skin.h>
#include <qsvgdial.h>
#include <qsvgbutton.h>
#include <qsvgled.h>
#include <qsvgslider.h>

class Pedal : public QWidget
{
    Q_OBJECT

public:
    explicit Pedal(QWidget *parent = 0);
    explicit Pedal(QString boxFile, QWidget *parent = 0);
    ~Pedal();
    int LoadSkin(skin skinfiles);
    QWidget* AddControl(QString type, QString param, int x, int y, int w, int h, QString file1, QString file2, QString file3, QString file4);

private:
    void resizeEvent(QResizeEvent *re);
    QRect PedalPosition();
    float myheight;
    float mywidth;
    float scale;
    int effectNumber;
    QGraphicsView view;
    QGraphicsScene scene;
    QGraphicsSvgItem *box;
    QSize p;
    QWidget* controls[20];
    QRect ctrlPos[20];
    int numControls;
};

#endif // PEDAL_H

父 cpp

#include "pedal.h"
#include "math.h"

Pedal::Pedal(QWidget *parent)
    : QWidget(parent)
{
    numControls = 0;
    box = new QGraphicsSvgItem("stompbox.svg");
    view.setStyleSheet("background: transparent; border: none");
    p = box->renderer()->defaultSize();
    box->setTransformOriginPoint(p.width()/2,p.height()/2);

    myheight = p.height();
    mywidth = p.width();
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scene.addItem(box);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}

Pedal::Pedal(QString boxFile, QWidget *parent) :
    QWidget(parent)
{
    numControls = 0;
    box = new QGraphicsSvgItem(boxFile);
    view.setStyleSheet("background: transparent; border: none");
    p = box->renderer()->defaultSize();
    box->setTransformOriginPoint(p.width()/2,p.height()/2);

    myheight = p.height();
    mywidth = p.width();
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scene.addItem(box);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}


Pedal::~Pedal()
{

}

void Pedal::resizeEvent(QResizeEvent *re)
{
    view.setFixedSize(this->width(),this->height());
    //view.move((this->width()-this->height())/2,(this->width()-this->height())/2);
    if (this->width()/mywidth>this->height()/myheight)
    {
        scale = this->height()/myheight;
    }
    else
    {
        scale = this->width()/mywidth;
    }
    box->setScale(scale);
    view.centerOn(box);
    //QWidget::resizeEvent(re);
    QRect v = PedalPosition();
    QRect cpos;
    for(int i = 0; i<numControls; i++)
    {
        cpos = ctrlPos[i];
        controls[i]->setGeometry(v.x()+cpos.x()*scale,v.y()+cpos.y()*scale,cpos.width()*scale,cpos.height()*scale);
    }
}

QWidget* Pedal::AddControl(QString type, QString param, int x, int y, int w, int h, QString file1, QString file2, QString file3, QString file4)
{
    QWidget* control;
    if (type.toLower() == "dial")
    {
        if (!file2.isEmpty())
            control = new qSVGDial(file1,file2,this);
        else
            control = new qSVGDial(this);
    }
    else if (type.toLower() == "button")
    {
        if (!file2.isEmpty())
            control = new qSVGButton(file1,file2,this);
        else if (!file1.isEmpty())
            control = new qSVGButton(file1,this);
        else
            control = new qSVGButton(this);
    }
    else if (type.toLower() == "slider")
    {
        if (!file2.isEmpty())
            control = new qSVGSlider(file1,file2,this);
        else if (!file1.isEmpty())
            control = new qSVGSlider(file1,this);
        else
            control = new qSVGSlider(this);
    }
    else if (type.toLower() == "led")
    {
        if (!file2.isEmpty())
            control = new qSVGLED(file1,file2,this);
        else
            control = new qSVGLED(this);
    }
    control->setToolTip(param);
    ctrlPos[numControls] = QRect(x,360-y-h,w,h);
    controls[numControls] = control;
    numControls++;
    return control;
}

QRect Pedal::PedalPosition()
{
    QRect mypos;
    mypos.setWidth(mywidth*scale);
    mypos.setHeight(myheight*scale);
    mypos.setX((this->width()-mypos.width())/2);
    mypos.setY((this->height()-mypos.height())/2);
    return mypos;
}

最后是测试 main

#include <QtGui/QApplication>
#include "pedal.h"

#include <string.h>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Pedal w("skins/default/stompbox.svg",0);
    w.AddControl("Dial" , "Level", 133, 295, 47, 47, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Button", "On", 20, 21, 182, 111, "skins/default/blackButton.svg","","","");
    w.AddControl("LED", "On", 106, 328, 11, 11, "skins/default/redLEDOff.svg", "skins/default/redLEDOn.svg","","");
    w.AddControl("Dial", "Gain", 44, 295, 47, 47, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Dial", "Low", 36, 244, 31, 31, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Dial", "Mid", 98, 244, 31, 31, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Dial", "High", 160, 244, 31, 31, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.show();

    return a.exec();
}

希望这会有所帮助。正如您所看到的,我有 QGraphicsViews 层,每个层都有一个小部件。我怀疑现在这可能是最糟糕的方法,所以我想知道在我朝着糟糕的方向前进之前是否有人有更多的经验。另外,在玩了更多之后,当我有 2 个 qSVGDial 实例时似乎会出现问题。如果我加载其他小部件组合,它就可以正常工作。再次感谢大家!

So I'm trying to make a gui for a guitar effects program. One goal is to allow others to design svg "skins" to customize the look. I made widgets that inherited each widget (i.e. qdial) and in the initializer load the svg file specified by the skin into a qGraphicsSvgItem. This is put into a scene and a view and I overloaded the resize and repaint appropriately. This works.

When I load several of these custom svg widgets (5 dials, a button, and an led) into a parent widget the cpu rails and my program freezes. Am I going about this entirely the wrong way? Should I even be using QT? It seemed easier than trying to do everything with a stylesheet (especially I couldn't figure out how to change the dial appearance). Would it improve things to leave the widgets as qGraphicsSvgItems and put them all into the parent widget's scene and view?

This is meant to be a real time signal processing program so I don't want to burn up a lot of cpu in the GUI. I tried to do some research on it but couldn't find a lot for svg. I also don't see any performance checker in qtCreator or I'd try to see what the bottleneck is. Anyway I'd really appreciate any advice you could offer before I spend more time trying to do something the wrong way.

Thanks so much!
_ssj71

p.s.
Here is some of the code (hopefully enough)
an svg widget:

#ifndef QSVGDIAL_H
#define QSVGDIAL_H

#include <QWidget>
#include <QDial>
#include <QtSvg/QSvgRenderer>
#include <QtSvg/QGraphicsSvgItem>
#include <QGraphicsView>
#include <QGraphicsScene>

class qSVGDial : public QDial
{
    Q_OBJECT

public:
    explicit qSVGDial(QWidget *parent = 0);
    explicit qSVGDial(QString knobFile = "defaultKnob.svg", QString needleFile = "defaultNeedle.svg", QWidget *parent = 0);
    ~qSVGDial();

private:
    void paintEvent(QPaintEvent *pe);
    void resizeEvent(QResizeEvent *re);
    float degPerPos;
    float middle;
    float mysize;
    QGraphicsView view;
    QGraphicsScene scene;
    QGraphicsSvgItem *knob;
    QGraphicsSvgItem *needle;
    QSize k,n;

};

#endif // QSVGDIAL_H

the cpp:

#include "qsvgdial.h"
#include "math.h"

qSVGDial::qSVGDial(QWidget *parent) :
    QDial(parent)
{
    knob = new QGraphicsSvgItem("defaultKnob.svg");
    needle = new QGraphicsSvgItem("defaultNeedle.svg");
    view.setStyleSheet("background: transparent; border: none");

    k = knob->renderer()->defaultSize();
    n = needle->renderer()->defaultSize();
    needle->setTransformOriginPoint(n.width()/2,n.height()/2);
    knob->setTransformOriginPoint(k.width()/2,k.height()/2);
    degPerPos = 340/(this->maximum() - this->minimum());
    middle = (this->maximum() - this->minimum())/2;
    mysize = k.width();
    if (mysize<n.width())  mysize = n.width();
    if (mysize<k.height()) mysize = k.height();
    if (mysize<n.height()) mysize = n.height();
    mysize = sqrt(2)*mysize;
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    scene.addItem(knob);
    scene.addItem(needle);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}

qSVGDial::qSVGDial(QString knobFile, QString needleFile, QWidget *parent) :
    QDial(parent)
{
    knob = new QGraphicsSvgItem(knobFile);
    needle = new QGraphicsSvgItem(needleFile);
    view.setStyleSheet("background: transparent; border: none");
    k = knob->renderer()->defaultSize();
    n = needle->renderer()->defaultSize();
    needle->setTransformOriginPoint(n.width()/2,n.height()/2);
    knob->setTransformOriginPoint(k.width()/2,k.height()/2);
    if (k!=n)
        needle->setPos((k.width()-n.width())/2,(k.height()-n.height())/2);

    degPerPos = 340/(this->maximum() - this->minimum());
    middle = (this->maximum() - this->minimum())/2;
    mysize = k.width();
    if (mysize<n.width())  mysize = n.width();
    if (mysize<k.height()) mysize = k.height();
    if (mysize<n.height()) mysize = n.height();
    mysize = sqrt(2)*mysize;
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scene.addItem(knob);
    scene.addItem(needle);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}

qSVGDial::~qSVGDial()
{
    //delete ui;

}

void qSVGDial::paintEvent(QPaintEvent *pe)
{
   needle->setRotation((this->sliderPosition() - middle)*degPerPos);
}

void qSVGDial::resizeEvent(QResizeEvent *re)
{
    if (this->width()>this->height())
    {
        view.setFixedSize(this->height(),this->height());
        view.move((this->width()-this->height())/2,0);
        knob->setScale(this->height()/mysize);
        needle->setScale(this->height()/mysize);
        view.centerOn(knob);
    }
    else
    {
        view.setFixedSize(this->width(),this->width());
        view.move(0,(this->height()-this->width())/2);
        knob->setScale(this->width()/mysize);
        needle->setScale(this->width()/mysize);
        view.centerOn(knob);
    }
    QDial::resizeEvent(re);
}

The parent header:

#ifndef PEDAL_H
#define PEDAL_H

#include <QtGui/QWidget>
#include <QString>
#include <QtSvg/QSvgRenderer>
#include <QtSvg/QGraphicsSvgItem>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <skin.h>
#include <qsvgdial.h>
#include <qsvgbutton.h>
#include <qsvgled.h>
#include <qsvgslider.h>

class Pedal : public QWidget
{
    Q_OBJECT

public:
    explicit Pedal(QWidget *parent = 0);
    explicit Pedal(QString boxFile, QWidget *parent = 0);
    ~Pedal();
    int LoadSkin(skin skinfiles);
    QWidget* AddControl(QString type, QString param, int x, int y, int w, int h, QString file1, QString file2, QString file3, QString file4);

private:
    void resizeEvent(QResizeEvent *re);
    QRect PedalPosition();
    float myheight;
    float mywidth;
    float scale;
    int effectNumber;
    QGraphicsView view;
    QGraphicsScene scene;
    QGraphicsSvgItem *box;
    QSize p;
    QWidget* controls[20];
    QRect ctrlPos[20];
    int numControls;
};

#endif // PEDAL_H

parent cpp

#include "pedal.h"
#include "math.h"

Pedal::Pedal(QWidget *parent)
    : QWidget(parent)
{
    numControls = 0;
    box = new QGraphicsSvgItem("stompbox.svg");
    view.setStyleSheet("background: transparent; border: none");
    p = box->renderer()->defaultSize();
    box->setTransformOriginPoint(p.width()/2,p.height()/2);

    myheight = p.height();
    mywidth = p.width();
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scene.addItem(box);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}

Pedal::Pedal(QString boxFile, QWidget *parent) :
    QWidget(parent)
{
    numControls = 0;
    box = new QGraphicsSvgItem(boxFile);
    view.setStyleSheet("background: transparent; border: none");
    p = box->renderer()->defaultSize();
    box->setTransformOriginPoint(p.width()/2,p.height()/2);

    myheight = p.height();
    mywidth = p.width();
    view.setDisabled(true);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    scene.addItem(box);
    view.setScene(&scene);
    view.setParent(this,Qt::FramelessWindowHint);
}


Pedal::~Pedal()
{

}

void Pedal::resizeEvent(QResizeEvent *re)
{
    view.setFixedSize(this->width(),this->height());
    //view.move((this->width()-this->height())/2,(this->width()-this->height())/2);
    if (this->width()/mywidth>this->height()/myheight)
    {
        scale = this->height()/myheight;
    }
    else
    {
        scale = this->width()/mywidth;
    }
    box->setScale(scale);
    view.centerOn(box);
    //QWidget::resizeEvent(re);
    QRect v = PedalPosition();
    QRect cpos;
    for(int i = 0; i<numControls; i++)
    {
        cpos = ctrlPos[i];
        controls[i]->setGeometry(v.x()+cpos.x()*scale,v.y()+cpos.y()*scale,cpos.width()*scale,cpos.height()*scale);
    }
}

QWidget* Pedal::AddControl(QString type, QString param, int x, int y, int w, int h, QString file1, QString file2, QString file3, QString file4)
{
    QWidget* control;
    if (type.toLower() == "dial")
    {
        if (!file2.isEmpty())
            control = new qSVGDial(file1,file2,this);
        else
            control = new qSVGDial(this);
    }
    else if (type.toLower() == "button")
    {
        if (!file2.isEmpty())
            control = new qSVGButton(file1,file2,this);
        else if (!file1.isEmpty())
            control = new qSVGButton(file1,this);
        else
            control = new qSVGButton(this);
    }
    else if (type.toLower() == "slider")
    {
        if (!file2.isEmpty())
            control = new qSVGSlider(file1,file2,this);
        else if (!file1.isEmpty())
            control = new qSVGSlider(file1,this);
        else
            control = new qSVGSlider(this);
    }
    else if (type.toLower() == "led")
    {
        if (!file2.isEmpty())
            control = new qSVGLED(file1,file2,this);
        else
            control = new qSVGLED(this);
    }
    control->setToolTip(param);
    ctrlPos[numControls] = QRect(x,360-y-h,w,h);
    controls[numControls] = control;
    numControls++;
    return control;
}

QRect Pedal::PedalPosition()
{
    QRect mypos;
    mypos.setWidth(mywidth*scale);
    mypos.setHeight(myheight*scale);
    mypos.setX((this->width()-mypos.width())/2);
    mypos.setY((this->height()-mypos.height())/2);
    return mypos;
}

finally the test main

#include <QtGui/QApplication>
#include "pedal.h"

#include <string.h>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Pedal w("skins/default/stompbox.svg",0);
    w.AddControl("Dial" , "Level", 133, 295, 47, 47, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Button", "On", 20, 21, 182, 111, "skins/default/blackButton.svg","","","");
    w.AddControl("LED", "On", 106, 328, 11, 11, "skins/default/redLEDOff.svg", "skins/default/redLEDOn.svg","","");
    w.AddControl("Dial", "Gain", 44, 295, 47, 47, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Dial", "Low", 36, 244, 31, 31, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Dial", "Mid", 98, 244, 31, 31, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.AddControl("Dial", "High", 160, 244, 31, 31, "skins/default/blackKnob.svg", "skins/default/whiteNeedle.svg","","");
    w.show();

    return a.exec();
}

hopefully this helps. As you can see I have layers of QGraphicsViews each with one widget. I suspect now this might be the worst way to do it so I wonder if anyone has more experience before I move forward in a bad direction. Also after playing some more with it, the problem seems to occur when I have 2 instances of the qSVGDial. If I load other combinations of widgets it works alright. Thanks again everyone!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦言归人 2024-12-13 19:19:54
void qSVGDial::paintEvent(QPaintEvent *pe)
{
   needle->setRotation((this->sliderPosition() - middle)*degPerPos);
}

这对我来说看起来很可疑。任何可能导致 PaintEvent 方法重绘的行为都是危险的,可能会导致无限更新循环。

您应该将表盘的 sliderMoved 信号连接到类中的一个槽并旋转该槽中的针,然后完全删除 paintEvent 处理程序。如果这没有触发更新,也可以在该插槽中调用 update() ,但我认为这没有必要。

(要首先检查这是否是问题所在,请尝试在 paintEvent 处理程序内向控制台打印一些内容。如果它打印得像疯了,那就是你的问题。)

void qSVGDial::paintEvent(QPaintEvent *pe)
{
   needle->setRotation((this->sliderPosition() - middle)*degPerPos);
}

This looks very suspicious to me. Doing anything that could result in a redraw from the paintEvent method is dangerous, could lead to infinite update loops.

You should connect the dial's sliderMoved signal to a slot in your class and rotate the needle in that slot, and remove the paintEvent handler altogether. If that doesn't trigger an update, call update() in that slot too, but I don't think this should be necessary.

(To check if this is the problem in the first place, try printing something to the console inside the paintEvent handler. If it prints like crazy, that's your problem.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文