Jump to content

[C/C++] QT Callback soll Daten in ein Label schreiben


Gast max

Recommended Posts

Hallo, ich versuche mich momentan dran ein Grafische Oberfläche zu programmiern mit Hilfe von QT.

 

Ich schaffe es daten per klick abzufragen und dann auszugeben die ausgaben auf der Software seite und sogra auf der Hardware Segmetanzeige....

 

Jetzt mein Problem wie schaffe ich das der Callback Temperature die Tempertur in ein Label schreibt?

 

const uint8_t digits[] = {0x3f,0x06,0x5b,0x4f,
                          0x66,0x6d,0x7d,0x07,
                          0x7f,0x6f,0x77,0x7c,
                          0x39,0x5e,0x79,0x71,0x63}; // 0~9,A,b,C,d,E,F,°



void segment_error(int licht)
{


    uint8_t segmentserror[4] = {0b1000000, 0b1000000, 0b1000000, 0b1000000};
    segment_display_4x7_set_segments(&sd4x7, segmentserror, licht, false);
}

void cb_temperature( void *user_data){
    (void)user_data; // avoid unused parameter warning

    if (temperature_get_temperature(&t, &temperature)< 0){
          segment_error(licht);

            }
    temperature = temperature/100;


    uint8_t segmentstemp[4] = {digits[temperature/10], digits[temperature%10],0x63, digits[12]};
    segment_display_4x7_set_segments(&sd4x7, segmentstemp, licht, false);
  }

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


    // Create IP connection extern
    ipcon_create(&ipconextern);
    ipcon_create (&ipconintern);

    // Create device object intern
    temperature_create(&t, "dX3", &ipconextern);
    //segment_display_4x7_create(&sd4x7, "iX8", &ipconextern);


    // Create device object intern
    segment_display_4x7_create(&sd4x7, "iX8", &ipconintern);
    rotary_encoder_create(&dreher,"kLE", &ipconintern);


    // Connect to Intern

    ipcon_connect(&ipconintern, "localhost", PORT);

     // Connect to Extern
    ipcon_connect(&ipconextern, "192.168.2.115", PORT);
    uint8_t segmentsend[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
    segment_display_4x7_set_segments(&sd4x7, segmentsend, 0, false);



    //Callback Perioden Setzen
    temperature_set_temperature_callback_period(&t, 3000);
    rotary_encoder_set_count_callback_period(&dreher, 50);

     // Register temperature callback to function cb_temperature
    temperature_register_callback(&t,TEMPERATURE_CALLBACK_TEMPERATURE,(void*)cb_temperature,NULL);


}

MainWindow::~MainWindow()

{
    delete ui;

    //Segementanzeige Ausschalten
    uint8_t segmentsend[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
    segment_display_4x7_set_segments(&sd4x7, segmentsend, 0, false);
    ipcon_destroy(&ipconintern); // Calls ipcon_disconnect
    ipcon_destroy(&ipconextern); // Calls ipcon_disconnect}
}



void MainWindow::on_pushButton_clicked()
{
    uint8_t segmentsend[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
    segment_display_4x7_set_segments(&sd4x7, segmentsend, 0, false);
   }

void MainWindow::on_verticalSliderlicht_actionTriggered(int action)
{
    licht = ui->verticalSliderlicht->value();
    cb_temperature(NULL);
}

Link zu diesem Kommentar
Share on other sites

Zuerst solltest du die Signatur der cb_temperature Funktion korrigieren. Sie muss so sein:

 

void cb_temperature(int16_t temperature, void *user_data)

 

Dann brauchst du in der Callback Funktion die Temperatur auch nicht mehr zu erfragen, denn der Callback liefert sie dir.

 

Dann solltest du cb_temperature nicht mehr aus on_verticalSliderlicht_actionTriggered heraus aufrufen. Wenn du hier die Temperatur abfragen und anzeigen solltest du dafür eine eigene Funktion erstellen die die Temperatur abfragt und anzeigt, anstatt die Callback Funktion dazu zu verwenden.

 

Wenn dann die Callback Funktion so ist wie sie eigentlich sein sollte, dann kann es ans eigentliche Problem gehen, die Temperatur auf einem QLabel anzuzeigen. Dazu sind zwei Probleme zu lösen.

 

1) Die cb_temperature Funktion muss auf das MainWindow zugreifen können.

 

2) Die cb_temperature Funktion wird aus einem Thread aufgerufen. Qt GUI Elemente dürfen aber nicht aus Threads heraus benutzt werden.

 

Das lässt sich aber alles lösen. Für Problem 1) kann das user_data Parameter der cb_temperature Funktion benutzt werden. du übergibst als letztes Parameter this an die temperature_register_callback Funktion. Dann bekommt die cb_temperature Funktion diese als user_data Parameter übergeben:

 

void cb_temperature(int16_t temperature, void *user_data)
{
    MainWindow *that = (MainWindow *)user_data;

    // ...
}

// ...

temperature_register_callback(&t,TEMPERATURE_CALLBACK_TEMPERATURE,(void*)cb_temperature,this);

 

 

TO BE CONTINUED...

Link zu diesem Kommentar
Share on other sites

... CONTINUE. Irgendwie habe ich mich beim Schreiben verhaspelt und einen halbfertigen Beitrag gepostet.

 

Also weiter mit Problem 2). Mittels einer Queued-Signal-Slot Verbindung kann man aus jedem Thread heraus eine Funktion so aufrufen, dass sie mit dem GUI arbeiten darf. Dazu hier ein Beispiel Programm:

 

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QtGui/QLabel>

#include "ip_connection.h"
#include "bricklet_temperature.h"
#include "bricklet_segment_display_4x7.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);

signals:
    void temperatureChanged(int temperature);

private slots:
    void displayTemperature(int temperature);

private:
    static void temperatureCallback(int16_t temperature, void *user_data);

    IPConnection ipcon;
    Temperature temp;
    SegmentDisplay4x7 sd4x7;

    QLabel *label;
};

#endif // MAINWINDOW_H

 

mainwindow.cpp:

#include "mainwindow.h"

static const uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f,
                                  0x66, 0x6d, 0x7d, 0x07,
                                  0x7f, 0x6f, 0x77, 0x7c,
                                  0x39, 0x5e, 0x79, 0x71, 0x63}; // 0~9,A,b,C,d,E,F,°

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    label = new QLabel(this);

    QObject::connect(this, SIGNAL(temperatureChanged(int)),
                     this, SLOT(displayTemperature(int)),
                     Qt::QueuedConnection);

    ipcon_create(&ipcon);
    temperature_create(&temp, "dX3", &ipcon);
    segment_display_4x7_create(&sd4x7, "iX8", &ipcon);

    ipcon_connect(&ipcon, "localhost", 4223);

    temperature_set_temperature_callback_period(&temp, 1000);
    temperature_register_callback(&temp, TEMPERATURE_CALLBACK_TEMPERATURE,
                                  (void *)MainWindow::temperatureCallback, this);

    int16_t temperature = 0;
    temperature_get_temperature(&temp, &temperature);

    displayTemperature(temperature);
}

void MainWindow::displayTemperature(int temperature)
{
    temperature = temperature / 100;

    uint8_t segments[4] = { digits[temperature / 10], digits[temperature % 10], digits[16], digits[12] };

    segment_display_4x7_set_segments(&sd4x7, segments, 7, false);

    label->setText(QString::number(temperature) + " deg C");
}

void MainWindow::temperatureCallback(int16_t temperature, void *user_data)
{
    MainWindow *that = (MainWindow *)user_data;

    emit that->temperatureChanged(temperature);
}

 

Die MainWindow Klasse hat ein temperatureChanged Signal und einen displayTemperature Slot. Diese beiden werden dann Queued verbunden. Dadurch kann die temperatureCallback Funktion dann die displayTemperature Funktion so aufrufen, dass die mit dem GUI arbeiten darf und die Temperatur in ein QLabel schreiben kann.

 

Das sind jetzt möglicherweise ein paar viele Qt Konzepte und Details auf einmal. Wenn du noch Fragen hast, immer raus damit :)

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...