所以我試圖爲吉他效果程序製作一個gui。其中一個目標是讓其他人設計svg「皮膚」來定製外觀。我製作了繼承每個小部件(即qdial)的小部件,並在初始化程序中將由皮膚指定的svg文件加載到qGraphicsSvgItem中。這是放入一個場景和一個視圖,我適當地重載了調整大小和重新繪製。這工作。自定義外觀svg QT中的GUI部件,性能非常差
當我將這些自定義svg窗口小部件(5個撥號,一個按鈕和一個led)加載到父窗口小部件中時,cpu導軌和我的程序凍結。我是否完全用錯誤的方式來解決這個問題?我應該甚至使用QT嗎?這似乎比試圖用樣式表做所有事情更容易(特別是我無法弄清楚如何改變撥號外觀)。它會改進的東西離開小部件作爲qGraphicsSvgItems並把他們都放到父窗口小部件的場景和視圖?
這是一個實時信號處理程序,所以我不想在GUI中燒掉很多CPU。我試圖做一些研究,但無法找到很多svg。我也沒有在qtCreator中看到任何性能檢查器,或者我會嘗試查看瓶頸是什麼。無論如何,如果我花更多時間嘗試錯誤的做法,我會非常感謝您提供的任何建議。
非常感謝! _ssj71
p.s. 下面是一些代碼(希望足夠)的 的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;
}
終於測試主
#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實例時,問題似乎就會發生。如果我加載其他組件的組合,它的工作正常。再次感謝大家!
沒有看到你的代碼,我們可以」告訴你是否做錯了事。與位圖類型格式相比,SVG的渲染成本更高,因此無論您使用哪種工具包,都需要付出代價。你確定你需要SVG嗎? (我發現你看到這樣的放緩令人驚訝。)至於「Qt最好」,請不要問這種主觀問題 – Mat
對不起,我不是故意問這樣的問題。我只是想知道是否有一些我不知道爲此設計的庫。我想我不需要,但我喜歡工作和可擴展性。 – user962342
'QDial :: paintEvent'沒有被覆蓋內部調用,是否正確? – Troubadour