Podział na wątki w QT

0

Witam! Piszę aplikację rysującą wykres (biblioteka qcustomplot) na podstawie pobranych danych z portu szeregowego. Problem zaczyna się gdy do bufora załaduje się więcej niż jeden znak (wartość do 255 wyświetlana na wykresie). Program pomija resztę znaków. Pierwszym pomysłem jest zrobienie pętli która przesunie do tablicy "y" tyle znaków ile jest w buforze, jednak zastanawiam się, czy nie lepiej zrobić to w drugim wątku. Jak uzyskać dostęp do widgetu "wykres" w klasie dziedziczącej po QThread? Dobrze kombinuję, czy są lepsze sposoby na rozwiązanie tego problemu? Dodam jeszcze, że w przyszłości program będzie robił na podstawie zebranych danych obliczenia i przedstawiał je na drugim wykresie, co może zająć trochę czasu. Dane wejściowe na porcie to ok.2000 B/s czyli 2000 punktów na wykresie.

 private:
    Ui::MainWindow *ui;

    void searchDevices();
    void readData();

    QVector<double> x;
    int x_limit;
    QVector<double> y;
    int y_limit;
    int y_counter;
    QBuffer buffer;
    QByteArray r_data;
    unsigned char ch;
   bool ok;

 connect(port,&QSerialPort::readyRead,this,&MainWindow::readData);
 void MainWindow::readData()
{
    r_data = port->readAll();
    qDebug() << "r_data: " << r_data;
    ch = r_data.data()[0];
    qDebug() << "ch: " << ch;
    int wartosc = static_cast<int>(ch);
    qDebug() << "wartosc: " << wartosc;
    ui->textBrowser->setPlainText(ui->textBrowser->toPlainText() + ch);

    //test
   if(y_counter == (y_limit-1)){
       for(int i=0;y_counter>i;i++){
           y[i] = y[i+1];
       }
       y[y_counter] = wartosc;
   }
   else{
       y[y_counter] = wartosc;
       y_counter++;
   }
  ui->wykres->graph(0)->setData(x,y);
  ui->wykres->replot();
}
2

GUI możesz używać wyłącznie z głównego wątku programu (a dokładniej: tego, który utworzył QGuiApplication). Użycie wątków wydaje się tutaj błędem, chyba że QSerialPort jest blokujący.

Jeśli obliczenia są kosztowne obliczeniowo, to je przenieś do osobnego wątku, z którym porozumiewaj się za pomocą systemu sygnałów i slotów (ewentualnie jakoś inaczej synchronizuj).

Aha, jeszcze jedno: zalecam lekturę QThread:[dop. kq] you're doing it wrong.... Zmiana prawie sprzed dekady a dziedziczenie po QThread nadal silne :​(

0

Aha... Robienie czegoś bezpośrednio przez wątek na wykresie mogę sobie wybić z głowy, fajnie wiedzieć. Czyli program dostanie globalną tablicę "y" i wątek do robienia obliczeń. Małe pytanko, tak przy okazji. Czy konwersję wartości char na int i przesuwanie do tablicy "y" da się zrobić optymalniej, czy tak jest dobrze i nie ma co tu zmieniać? Jestem kompletnym laikiem, zrobiłem jak umiałem, zastanawiam się, jak można zrobić to lepiej.

3

Czytanie asynchroniczne (nieblokujące) powinno wystarczyć.

Tu masz przykład:
http://doc.qt.io/qt-5/qtserialport-creaderasync-example.html

Natomiast do rysowania powinieneś użyć jakiegoś wykresu który wspiera rysowanie "live", bo z przerysowaniem to raczej się nie uda.
Przykład: http://www.qcustomplot.com/index.php/demos/realtimedatademo

1 użytkowników online, w tym zalogowanych: 0, gości: 1