Donc j'essaye de faire un gui pour un programme d'effets de guitare. Un but est de permettre aux autres de concevoir des «skins» svg pour personnaliser le look. J'ai fait des widgets qui ont hérité de chaque widget (c'est-à-dire qdial) et dans l'initialiseur charge le fichier svg spécifié par le skin dans un qGraphicsSvgItem. Ceci est mis dans une scène et une vue et j'ai surchargé le redimensionner et repeindre de manière appropriée. Cela marche.Custom look svg widgets GUI en QT, très mauvaise performance
Lorsque je charge plusieurs de ces widgets personnalisés svg (5 cadrans, un bouton et un led) dans un widget parent les rails du processeur et mon programme se fige. Est-ce que je vais tout à fait dans le mauvais sens? Devrais-je même utiliser QT? Cela semblait plus facile que d'essayer de tout faire avec une feuille de style (surtout je ne pouvais pas comprendre comment changer l'apparence du cadran). Cela améliorerait-il les choses à laisser les widgets sous forme de qGraphicsSvgItems et les placer tous dans la scène et la vue du widget parent? Ceci est censé être un programme de traitement du signal en temps réel, donc je ne veux pas brûler beaucoup de cpu dans l'interface graphique. J'ai essayé de faire des recherches à ce sujet mais je n'ai pas trouvé beaucoup de choses pour svg. Je ne vois pas non plus de vérificateur de performance dans qtCreator ou j'essaierais de voir quel est le goulot d'étranglement. De toute façon j'apprécierais vraiment tout conseil que vous pourriez offrir avant que je passe plus de temps essayant de faire quelque chose dans le mauvais sens.
Merci beaucoup! _ssj71
p.s. Voici le code (je l'espère assez) un widget 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);
}
L'en-tête parent:
#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;
}
enfin la principale de test
#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();
}
espérons que cela aide. Comme vous pouvez le voir, j'ai des couches de QGraphicsViews avec un widget. Je soupçonne maintenant que cela pourrait être la pire façon de le faire, alors je me demande si quelqu'un a plus d'expérience avant d'aller de l'avant dans une mauvaise direction. Aussi après avoir joué un peu plus avec, le problème semble se produire quand j'ai 2 instances du qSVGDial. Si je charge d'autres combinaisons de widgets cela fonctionne bien. Merci encore tout le monde!
Sans voir votre code, nous pouvons » t dire si vous faites quelque chose de mal ou non.Le format SVG est plus coûteux que les formats de type bitmap, donc il y a un coût avec eux quelle que soit la boîte à outils que vous utilisez. Etes-vous sûr que vous avez besoin de SVG pour tous? (Je trouve surprenant que vous voyiez un tel ralentissement.) Quant à "est Qt meilleur", s'il vous plaît ne posez pas ce type de question subjective – Mat
Désolé, je ne voulais pas poser ce genre de question. Je me demandais juste s'il y a une bibliothèque que je ne connais pas conçue pour cela. Et je suppose que je n'ai pas besoin de svgs mais j'aime travailler dans inkscape et l'évolutivité. – user962342
'QDial :: paintEvent' n'est pas appelé depuis le remplacement, n'est-ce pas? – Troubadour