2

我有一个用 Qt 为嵌入式 linux 编写的图形应用程序。此应用程序的一部分是每 250 毫秒更新一次显示屏幕。但是,大约 8-10 小时后,应用程序崩溃并出现“QList:内存不足”错误。我已经隔离了函数和它发生的行(在某种意义上),但我不知道它为什么会发生,因为我没有使用 QList。此函数中唯一有效的代码行位于此问题的末尾。

我意识到 QList 永远不会“缩小”它用来保存项目的内存,但我没有在我的代码中的任何地方使用 QList。我只是调用“setStyleSheet”来在 ui 小部件(标签、文本字段等)上设置各种字体和属性。还有更多代码,但它们都被注释掉了,所以我假设它与 setStyleSheet 有关。有谁知道为什么会这样?如果是这样,你知道解决这个问题的方法吗?我正在使用 Qt 4.3 btw(由于它专门加载在我正在使用的嵌入式系统上)。

非常感谢您的时间。

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'}");
  }

编辑:

我应该提到,这些行基于来自另一个子系统的输入消息每 250 毫秒执行一次。我已经走了那条路,这是一条死胡同。这是错误代码。

4

1 回答 1

2

您使用 qstylesheets 的方式更多地用于静态属性。如果您打算即时更改属性,我会研究使用动态属性进行自定义

使用动态属性进行自定义

在很多情况下,我们需要提供一个包含必填字段的表单。为了向用户指示该字段是强制性的,一种有效的(尽管在美学上令人怀疑)解决方案是使用黄色作为这些字段的背景色。事实证明,使用 Qt 样式表很容易实现。首先,我们将使用以下应用程序范围的样式表:

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

这意味着每个部件的mandatoryField Qt 属性设置为 true 都将具有黄色背景。

然后,对于每个必填字段小部件,我们只需动态创建一个mandatoryField 属性并将其设置为true。例如:

 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);

频繁交换值似乎更友好。这在 Qt 4.7 中得到了很好的解释,但它似乎在 Qt 4.3 中仍然可用:样式表语法:选择器类型

所以基本上,不是一遍又一遍地添加到为您的应用程序设置的 q 样式表列表中,您应该使一些样式依赖于属性,并设置该属性,然后取消设置样式表,然后重新设置它。我相信这可以通过unpolishandpolish命令来完成(参见Styles and Style Aware Widgets)。

编辑:下面是使用这种技术的一个例子。有一个带有 QPushButton 的 mainwindow.ui。

主文件

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

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

    return a.exec();
}

主窗口.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

主窗口.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++;
}
于 2012-11-26T16:15:42.847 回答