Seite 1 von 1

Problem mit einbinden/aufrufen von QSerial [gelöst]

Verfasst: 22. Mai 2010 23:56
von Lukas
Hallo

Ich habe nun ein neues Projekt erstellt und würde gerne die Klasse sreader von QSerial http://qt-apps.org/content/show.php/QSe ... ent=112039 verwenden.

Ich habe nun die Datei sreader.h in mein Projekt als readers232.h & .cpp eingebaut.
Leider bekomme ich nun die Fehlermeldung dass die Methoden von abstractserial.h nicht gefunden werden.

Ich bin mir leider auch nicht ganz sicher welche Dateien aus dem QSerial Projekt ich überhaupt benötige, bzw wie ich sie sauber einbinde.
Fürs erste genügt mir nur Serielle Daten empfangen.

Was ich auch noch nicht ganz verstehe ist der Konstruktor von readrs232

Code: Alles auswählen

ReadRS232::ReadRS232(QObject *parent = 0)
    : QObject(parent)
In vorherigen Projekt Versuchen habe ich gemerkt dass

Code: Alles auswählen

connect(MyDevice, SIGNAL(readyRead()), this, SLOT(slotRead()));
nur dann funktioniert wenn

Code: Alles auswählen

ReadRS232 MyReader;
im Main Programm steht und nicht in einer MainWindow Methode. Ich nehme an, dass dieses Problem auch hier bestehen wird.

Im Projektfile von QSerial stehen zusätzlich noch eine Menge Einträge, bin mir da auch nicht ganz sicher welche nun wirklich benötige.

Bei Klick auf den Button sollte in der Debug Konsole die Empfangen Werte angezeigt werden, wenns denn mal funktioniert ;)

Könntet Ihr Euch bitte mein Projekt einmal ansehen.

Ganz großes Dankeschön an alle Tipps, Ratschläge und Reparatur Versuche.

schönen Abend lg Lukas

Verfasst: 23. Mai 2010 14:20
von Lukas
Ahh warum sagt denn keiner was..., Attachment war zu groß und kam nicht mit -.-

Hier ist nun mein Projektfile

Ganz großes Dankeschön an alle Tipps, Ratschläge und Reparatur Versuche.

lg Lukas

Verfasst: 30. Mai 2010 13:29
von Lukas
Hi

Könnte mir bitte jemand weiterhelfen.
Ich komm einfach nicht dahinter wie es richtig gemacht gehört.

Vielleicht hilft es ja wenn ich mal den ganzen Code poste:
test.pro

Code: Alles auswählen

TARGET = test2
TEMPLATE = app
SOURCES += main.cpp \
    mainwindow.cpp \
    readrs232.cpp
HEADERS += mainwindow.h \
    readrs232.h
FORMS += mainwindow.ui
main.cpp

Code: Alles auswählen

#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:

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void changeEvent(QEvent *e);

private:
    Ui::MainWindow *ui;
   void  init_objects();

private slots:
    void on_pushButton_clicked();
};

#endif // MAINWINDOW_H
mainwindow.cpp:

Code: Alles auswählen

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "readrs232.h"
#include "readrs232.cpp"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init_objects();
}

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

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
void MainWindow::init_objects()
{
  qDebug() << "test1";


}

void MainWindow::on_pushButton_clicked()
{
    ReadRS232 MyReader();

}
readrs232.h:

Code: Alles auswählen

#ifndef READRS232_H
#define READRS232_H

#include <QObject>


#include <QDebug>
#include <QByteArray>

#include <abstractserial.h>
using namespace std;

class ReadRS232 : public QObject
{
Q_OBJECT
public:
    ReadRS232(QObject *parent);
    ~ReadRS232();
    void ReadRS232open();

    AbstractSerial *MyDevice;
    int readBytes;
private slots:
    void slotRead();
};

#endif // READRS232_H
readrs232.cpp

Code: Alles auswählen

#include "readrs232.h"
#include <abstractserial.h>


static void printDataToHex(const QByteArray &data)
{
    QByteArray baTmp;
    baTmp.clear();
#if QT_VERSION >= 0x040300
    baTmp = (data.toHex()).toUpper();
#else
    quint8 n = 0;
    for (int i=0;i<data.size();i++) {
        n = data.at(i);
        if ((n >= 0) && (n <= 15)) baTmp.append(QByteArray::number(0, 16).toUpper());
        baTmp.append(QByteArray::number(n, 16).toUpper());
    }
#endif

    for (int i=0;i<baTmp.size();i+=2) {
        qDebug() << "[" << baTmp.at(i) << baTmp.at(i + 1) << "]";
    }
    qDebug() << endl;
}

ReadRS232::ReadRS232(QObject *parent = 0)
    : QObject(parent)
{
}
void ReadRS232::ReadRS232open()

    {
    MyDevice = new AbstractSerial();
    connect(MyDevice, SIGNAL(readyRead()), this, SLOT(slotRead()));
    MyDevice->setDeviceName("COM6");
    MyDevice->setBaudRate(AbstractSerial::BaudRate128000);

    //MyDevice->setBaudRate(AbstractSerial::BaudRate115200);

    if (!MyDevice->open(AbstractSerial::ReadOnly)) {
        qDebug() << "Serial device by default: " << MyDevice->deviceName() << " open fail.";
        return;
    }
    if (!MyDevice->setDataBits(AbstractSerial::DataBits8)) {
        qDebug() << "Set data bits " <<  AbstractSerial::DataBits8 << " error.";
        return;
    }

    if (!MyDevice->setParity(AbstractSerial::ParityNone)) {
        qDebug() << "Set parity " <<  AbstractSerial::ParityNone << " error.";
        return;
    }

    if (!MyDevice->setStopBits(AbstractSerial::StopBits1)) {
        qDebug() << "Set stop bits " <<  AbstractSerial::StopBits1 << " error.";
        return;
    }

    if (!MyDevice->setFlowControl(AbstractSerial::FlowControlOff)) {
        qDebug() << "Set flow " <<  AbstractSerial::FlowControlOff << " error.";
        return;
    }
    qDebug() << "= Default parameters =";
    qDebug() << "Device name            : " << MyDevice->deviceName();
    qDebug() << "Baud rate              : " << MyDevice->baudRate();
    qDebug() << "Data bits              : " << MyDevice->dataBits();
    qDebug() << "Parity                 : " << MyDevice->parity();
    qDebug() << "Stop bits              : " << MyDevice->stopBits();
    qDebug() << "Flow                   : " << MyDevice->flowControl();
    qDebug() << "Char timeout, msec     : " << MyDevice->charIntervalTimeout();
    readBytes = 5;


}

ReadRS232::~ReadRS232() {
    MyDevice->close();
    delete MyDevice;
    MyDevice = 0;
}

void ReadRS232::slotRead() {
    QByteArray ba = MyDevice->read(readBytes);
    qDebug() << "Rx : \n";
    printDataToHex(ba);
    qDebug() << " \n Readed is : " << ba.size() << " bytes";
}
abstractserial.h und zugehörige Daten liegen in einem eigenen Ordner"qserialdevice"


Momentan bekomme ich eine Menge Fehlermeldungen wie diese hier:
debug/mainwindow.o:mainwindow.cpp::-1: error: undefined reference to `AbstractSerial::AbstractSerial(QObject*)'
bedeutet wohl dass die AbstractSerial.h nicht korrekt included ist oder?

Ist eigentlich ReadRS232 MyReader(); das selbe wie MyReader = new ReadRS232();? Wenn ich das umschreibe kommt die Meldung: H:/tricopter/qt/test2/test2/mainwindow.cpp:39: error: 'MyReader' was not declared in this scope


Ich blick da einfach nicht durch -.-

Großes Dankeschön für Eure Mühe

lg Lukas

Verfasst: 30. Mai 2010 14:12
von franzf
Lukas hat geschrieben:Ist eigentlich ReadRS232 MyReader(); das selbe wie MyReader = new ReadRS232();? Wenn ich das umschreibe kommt die Meldung: H:/tricopter/qt/test2/test2/mainwindow.cpp:39: error: 'MyReader' was not declared in this scope
Nein ist es nicht, beschäftige dich mal lieber erst mit Grundlagen, bevor du mit GUI/SerialPort/etc spielst... (Was ist ein Pointer? Was ist HEAP und was ist STACK und wie leg ich Objekte da rein? usw.)

Zum Problem: Du bindest die Bibliothek direkt in dein Projekt ein und verpanschst dann irgendwie das directory von QSerialDevice mit dem Deinigen, kopierst fremde Header und Sourcen rum usw, das kann nicht gut gehen.
Du solltest das QSerialDevice-Projekt separat (also außerhalb deines Projektes) kompilieren und installieren, die installierten Dateien (Header und Libs) dann in deinem eigenen Programm nutzen.
Helfen tun dir in deinem eigenen Programm die qmake-Variablen (Doku -> "qmake Variable Reference") INCLUDEPATH und LIBS.

Verfasst: 30. Mai 2010 15:58
von Lukas
Hi
Danke für deine Antwort

Grundsätzlich kenne ich die von dir genannten Begriffe aus anderen Programmiersprachen. Die Umsetzung in C++ fällt mir aber leider noch etwas schwer. http://www.cplusplus.com/doc/tutorial/ hat mir auf alle Fälle schon sehr geholfen.

Wenn ich das nun richtig verstanden habe, sollte ich mit INCLUDEPATH += ./qserialdevice die Header Datein hinzufügen.
Und dann die Lib mit LIBS += -lqserialdevice hinzufügen
Unter qserialdevice liegen aber hauptsächlich nur *.h und *.cpp datein.
Ich nehme an dass die Lib diese Datei ist: build\lib\qintegratedserialdevice\release\libqserialdevice.a oder?

Danke für Eure Mühe

lg Lukas

Verfasst: 30. Mai 2010 17:41
von franzf
Du sollst den ganzen qserialdevice-codetree aus deinem Code rausmnehmen!
Bau das Ding separat, installier es. Das installiert dir die lib und die Header, die du mit den genannten Variablen (im .pro oder per cmd-line übergeben) bekannt geben kannst.

Wenn du darauf bestehst, dass qserialdevice immer mitgeliefert wird (was gegen alle Gewohnheiten im Linux-Umfeld geht und mehr bei MS zu Hause ist...) dann leg einen separaten Ordner in deinem Tree "3rdparty" (z.B.) an, wo du die kompletten Projekte reinnimmst. So trennst du eindeutig deinen Code von fremdem. Aber das machst du bitte nicht...

Verfasst: 30. Mai 2010 19:29
von Lukas
Ich versteh nicht ganz, wie "installiere" ich qserialdevice, bzw. was darf ich unter installieren verstehen?

Es gibt 2 Projektfiles: BuildIntegratedLibrary.pro und BuildDifferentiatedLibrary.pro.
Was ist der Unterschied zwischen integrated und differential?

Ich kann das Projekt File öffnen und es Ausführen.

In der Doku die beim Projekt dabei war, gibt es zwar einen Punkt "Installation", aber der ist leer.

Nochmals Danke für deine Mühe

lg Lukas

Verfasst: 30. Mai 2010 19:49
von franzf
Lukas hat geschrieben:Ich versteh nicht ganz, wie "installiere" ich qserialdevice, bzw. was darf ich unter installieren verstehen?
Scheinbar baut der kein install-target (habs grad mal ausprobiert). Doll.
Das ist nicht recht schön, weil es den Programmierer nötigt, immer eine Kopie selber mitzuliefern :( Mist...
Dann bleibt dir nur .a kopieren. Diese Dinger sind statische Libraries, die dann ins executable gelinkt werden.
Es gibt 2 Projektfiles: BuildIntegratedLibrary.pro und BuildDifferentiatedLibrary.pro.
Was ist der Unterschied zwischen integrated und differential?
Ausprobieren? Dann siehst du dass integrated nur eine library baut, Differentiated dagegen für serialdevice/serialdevicewatcher/serialdeviceinfo jeweils eine eigene. Hätte den Vorteil, dass du nur das linken musst, was du auch brauchst.

Verfasst: 30. Mai 2010 20:23
von Lukas
Danke für deine Antwort und dass du dir die Mühe gemacht hast das extra auszuprobieren,

Sollte die *.a in einem eigenen Ordner liegen oder bei den Projektdatein?

Müssen zusätzlich auch noch die *.h Datein von qserial mitkopiert werden oder stehen diese Daten auch in der *.a?

Wie kann ich nun die *.a dem Linker bekannt geben? mit LIBS += libqserialdevice.a ?

Ändert sich am Eintrag #include <abstractserial.h> etwas?

nochmals großes Danke für deine Mühe

lg Lukas

Verfasst: 30. Mai 2010 21:07
von Lukas
Soo
mit LIBS += ./libqserialdevice.a lässt sich das Projekt erst mal ausführen *freu*
Nun hab ich aber feststellen müssen dass nach ReadRS232 MyReader(); der Konstruktor ReadRS232::ReadRS232(QObject *parent = 0) wohl nicht aufgerufen wird.
Werd mir das mal ansehen, vielleicht komm ich ja noch selbst drauf.
Also erstmal großes Danke für deine Mühen

schönen Abend
lg Lukas

Verfasst: 31. Mai 2010 07:05
von kuzulis
Lukas,

Wenn Sie es schwer zu verstehen, wie zu kompilieren und zu finden, verwenden Sie die Bibliothek, dann können Sie einfacher: Schließen Sie Ihren *.pro Projekt-Datei nur AND/OR:
qserialdevice.pri,
qserialdeviceinfo.pri,
qserialdevicewatcher.pri.

dh Verbindung *.pri - Dateien in Ihrem Entwurf ist eine gleichwertige Verbindung *.h und *.cpp - Dateien.

Wenn Sie *.pri wird einfacher - verwenden Sie dann *.pri.

PS: Sorry für die schlechte Google Translate :)

Verfasst: 31. Mai 2010 22:00
von Lukas
Hallo

Danke für Eure Hilfe, es scheint nun alles zu funktionieren.

Außerdem habe ich nun nochmals vieeeeel Doku studiert und konnte nun auch mein neues Problem lösen. Hoff ich habs nun verstanden ;)

Code: Alles auswählen

void MainWindow::on_pushButton_clicked()
{   ReadRS232 * MyReader;
    MyReader = new ReadRS232;
}
2 Zeilen code bei denen man sooo viel falsch machen kann wenn man keine Ahnung hat;)

Einige #include waren auch noch falsch.

Nun werden fleißig Pakete empfangen die ich verarbeiten kann *freu* *hüpf* *freu*

Die *.pri Daten direkt einbinden werde ich auch mal versuchen, glaube aber die *.a einzubinden ist die vernünftigere Lösung.

Nochmals ganz großes Dankeschön an Alle

schönen Abend

lg Lukas