2 votes

QList : Mémoire insuffisante

J'ai une application graphique écrite en Qt pour linux embarqué. Une partie de cette application consiste à mettre à jour un écran d'affichage toutes les 250 ms. Cependant, après environ 8-10 heures, l'application se bloque avec un message "QList : Out of memory". J'ai isolé la fonction et les lignes (dans un sens) où cela se produit, mais je n'ai aucune idée de la raison pour laquelle cela se produit puisque je n'utilise pas QList. Les seules lignes de code actives dans cette fonction se trouvent à la fin de cette question.

Je sais que QList ne "réduit" jamais la mémoire qu'elle utilise pour contenir les éléments, mais je n'utilise QList nulle part dans mon code. Je n'appelle 'setStyleSheet' que pour définir diverses polices et propriétés sur les widgets de l'interface utilisateur (étiquettes, champs de texte, etc.). Il y a plus de code, mais il est entièrement commenté, donc je suppose qu'il a quelque chose à voir avec setStyleSheet. Quelqu'un sait-il pourquoi cela se produit ? Si oui, connaissez-vous un moyen de le contourner ? J'utilise Q.t. 4.3 btw (en raison de son chargement spécifique sur le système embarqué que j'utilise).

Merci beaucoup pour votre temps.

if(twc_rx){
        ui->label_Rx->setStyleSheet("QLabel { background-color: lime; font: bold 16px 'Arial' }");
  }else if(!twc_rx){
    ui->label_Rx->setStyleSheet("QLabel { background-color: grey; font: bold 16px 'Arial' }");

  }//line 561 to 684
  if(twc_tx){
   ui->label_Tx->setStyleSheet("QLabel { background-color: lime; font: bold 16px 'Arial' }");
  }else{
   ui->label_Tx->setStyleSheet("QLabel { background-color: grey; font: bold 16px 'Arial' }");
  }if(ats_stat){
       ui->label_ATS->setStyleSheet("QLabel { background-color: lime; border-radius: 10; font: bold 16px 'Arial'}");
  }else{
       ui->label_ATS->setStyleSheet("QLabel { background-color: red; border-radius: 10; font: bold 16px 'Arial'}");
  }
  if(atp_stat){
       ui->label_atp2->setStyleSheet("QLabel { background-color: lime; border-radius: 10; font: bold 16px 'Arial'}");
  }else{
       ui->label_atp2->setStyleSheet("QLabel { background-color: red; border-radius: 10; font: bold 16px 'Arial'}");
  }
  if(ato_stat){
       ui->label_ATO->setStyleSheet("QLabel { background-color: lime; border-radius: 10; font: bold 16px 'Arial'}");

  }else{
       ui->label_ATO->setStyleSheet("QLabel { background-color: red; border-radius: 10; font: bold 16px 'Arial'}");
  }

EDIT :

Je dois préciser que ces lignes sont exécutées toutes les 250 ms en fonction d'un message d'entrée provenant d'un autre sous-système. J'ai déjà emprunté cette voie et c'est une impasse. Voici le code d'erreur.

2voto

phyatt Points 6647

La façon dont vous utilisez les qstylesheets est plutôt destinée aux propriétés statiques. Si vous avez l'intention de modifier les propriétés à la volée, je me pencherais sur les options suivantes Personnalisation à l'aide de propriétés dynamiques .

Personnalisation à l'aide de propriétés dynamiques

Il y a de nombreuses situations où nous des champs obligatoires. Pour indiquer à l'utilisateur que le champ est obligatoire, une solution efficace (bien qu'esthétiquement douteuse) consiste à utiliser le jaune comme couleur de fond pour ces champs. Il s'avère que cette solution est très facile à mettre en œuvre à l'aide des feuilles de style Qt. Tout d'abord, nous utiliserions l'élément feuille de style suivante pour l'ensemble de l'application :

 *[mandatoryField="true"] { background-color: yellow }

Cela signifie que chaque widget dont la propriété Qt mandatoryField est définie à true aura un fond jaune.

Ensuite, pour chaque widget de champ obligatoire, nous devons simplement créer une propriété mandatoryField à la volée et de lui attribuer la valeur true. Par exemple :

 QLineEdit *nameEdit = new QLineEdit(this);
 nameEdit->setProperty("mandatoryField", true);

 QLineEdit *emailEdit = new QLineEdit(this);
 emailEdit->setProperty("mandatoryField", true);

 QSpinBox *ageSpinBox = new QSpinBox(this);
 ageSpinBox->setProperty("mandatoryField", true);

Il semble plus convivial pour les échanges fréquents de valeurs. Ceci est bien expliqué pour Qt 4.7, mais il semble qu'il soit encore disponible dans Qt 4.3 : La syntaxe de la feuille de style : Types de sélecteurs

En gros, au lieu d'ajouter sans cesse à la liste des feuilles de style définies pour votre application, vous devriez faire en sorte que certains des styles dépendent d'une propriété, et définir cette propriété, puis annuler la feuille de style et la redéfinir. Je crois que cela peut être fait avec la fonction unpolish y polish (voir Styles et widgets sensibles au style ).

EDIT : Voici un exemple d'utilisation de cette technique. Il y a une mainwindow.ui avec un QPushButton dessus.

main.cpp

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimerEvent>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void timerEvent(QTimerEvent *);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString stylesheet =
            "*[mandatoryField=\"true\"] { background-color: yellow }"
            "*[mandatoryField=\"false\"] { background-color: gray }"
            "QPushButton[otherField=\"true\"] { border: none; }"
            "QPushButton[otherField=\"false\"] { border-color: navy; }";
    ui->pushButton->setProperty("mandatoryField", true);
    ui->pushButton->setProperty("otherField", true);
    ui->pushButton->setStyleSheet(stylesheet);

    this->startTimer(1000);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::timerEvent(QTimerEvent *)
{
    static int count = 0;

    if(count % 2)
    {
        bool previousMandatoryFieldValue = ui->pushButton->property("mandatoryField").toBool();
        ui->pushButton->setProperty("mandatoryField", !previousMandatoryFieldValue);
        qDebug() << "mf" << previousMandatoryFieldValue;
    }
    else
    {
        bool previousOtherFieldValue = ui->pushButton->property("otherField").toBool();
        ui->pushButton->setProperty("otherField", !previousOtherFieldValue);
        qDebug() << "of" << previousOtherFieldValue;
    }
    ui->pushButton->style()->unpolish(ui->pushButton);
    ui->pushButton->style()->polish(ui->pushButton);

    this->update();

    count++;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X