Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

main window doesn't open although program is running



  • Hi,

    I have a small gui that should display some voltage values that comes in over a serial port.
    The thing is that the gui is not loaded after starting the programm, although I see the values comming in in the debug output. So the programm itself is running somehow.
    When I remove the part where I read the serial port the gui is shown.

    What is wrong here?

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    { 
        strVoltages << "Voltage 1" << "Voltage 2" << "Voltage 3";
    
        ui->setupUi(this);
        this->createLayout();
    
        this->readValues();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::readValues() {
        QSerialPort port;
        port.setPortName("COM3");
        port.setBaudRate(115200);
        port.setDataBits(QSerialPort::Data8);
        port.setParity(QSerialPort::NoParity);
        port.setStopBits(QSerialPort::OneStop);
        port.setFlowControl(QSerialPort::NoFlowControl);
    
        if (!port.open(QSerialPort::ReadWrite)) {
            qDebug() << "Error opening serial port: " << port.errorString() << endl;
        }
        else {
            while(1) {
                while (!port.canReadLine())
                    port.waitForReadyRead(-1);
    
                while (port.canReadLine()) {
                    QString strIn(port.readLine());
                    QStringList strList = strIn.split(',');
    
                    if(strList.count() == strVoltages.length()) {
                        int iLCDCounter = 0;
                        foreach(QString strTmp, strList) {
                            lLCDNumber.at(iLCDCounter++)->display(strTmp);
                            qDebug() << strTmp;
    
                        }
                    }
                }
            }
        }
    }
    
    void MainWindow::createLayout() {
    
        QVBoxLayout * vBoxLayout = new QVBoxLayout();
    
        for(int iItr = 0; iItr < strVoltages.length(); iItr++) {
            lDescription.append(new QLabel(strVoltages.at(iItr)));
            lLCDNumber.append(new QLCDNumber());
    
            QHBoxLayout *hBoxLayout = new QHBoxLayout();
            hBoxLayout->addWidget(lDescription.last());
            hBoxLayout->addWidget(lLCDNumber.last());
    
            vBoxLayout->addLayout(hBoxLayout);
        }
    
        QWidget *w = new QWidget();
        w->setLayout(vBoxLayout);
    
        setCentralWidget(w);
    }
    
    

    Thanks!



  • @LeoC said in main window doesn't open although program is running:

    while(1) {

    That loop never exits.

    Your code/GUI might be better written using signals for reading the data instead of waitForReadyRead() etc. Get the main window up & showing without waiting, and display the values as & when they arrive via signals/slots.



  • why do you use while(1)??? have you heard of signal and slot?? use it!!

    while(1) is useful for programming microcontrollers .. In Qt we use signal and slots



  • @LeoC said in main window doesn't open although program is running:

    What is wrong here?

    It looks like the while() loop... You are supposed to work with signals & slots in Qt.

    You may want to look at this example for serial terminal. I guess you'll grasp a good idea about how to work with the serial port



  • Sorry for my late response.

    It isn't the first time I use Qt and I heard about signals and slots of course. In this case I needed a very fast (and maybe dirty) solution so that I just copied 'something' from the internet. Shouldn't do this again. After you gave me the right hint I abandoned the above solution (since it didn't worked anyway) and started from scratch again. Not it works as it should do.

    If someone is interested:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    { 
        strVoltages << "Voltage 1" << "Voltage 2" << "Voltage 3";
        iMinSize = (3 * strVoltages.count() + strVoltages.count() - 1);
        iMaxSize = (4 * strVoltages.count() + strVoltages.count() - 1);
        bInvokedFirstTime = false;
        bInvokedSecondTime = false;
    
        ui->setupUi(this);
        this->setWindowTitle("Voltmeter");
    
        connect(&port,SIGNAL(readyRead()),this,SLOT(readValues()));
    
        this->createLayout();
    
        this->configureSerialPort();
        this->readValues();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::configureSerialPort() {
        port.setPortName("COM3");
        port.setBaudRate(115200);
        port.setDataBits(QSerialPort::Data8);
        port.setParity(QSerialPort::NoParity);
        port.setStopBits(QSerialPort::OneStop);
        port.setFlowControl(QSerialPort::NoFlowControl);
    
        if (!port.open(QSerialPort::ReadWrite)) {
            qDebug() << "Error opening serial port: " << port.errorString() << endl;
        }
        else
            qDebug() << "Serial port is ready";
    }
    
    void MainWindow::displayValues(QByteArray baTmp) {
        
        QStringList strListValues = QString(baTmp).split(",");
    
        int iLoopCounter = 0;
        foreach(QString strTmp, strListValues) {
            lLCDNumber.at(iLoopCounter)->display(strTmp);
    
            bool bCheck;
            double dNumber = strTmp.toDouble(&bCheck);
    
            if(dNumber < 10)
                lIndicator.at(iLoopCounter)->setStyleSheet("QLabel { background-color : red; }");
    
            iLoopCounter++;
        }
    }
    
    void MainWindow::readValues() {
    
        if(bInvokedFirstTime) {
            baDataIn.append(port.readAll());
    
            if(!bInvokedSecondTime) {
                int iPosOfExlM = baDataIn.indexOf("!");
                if(iPosOfExlM < iMinSize) {
                    baDataIn = baDataIn.right(baDataIn.length() - (iPosOfExlM+1));
                    bInvokedSecondTime = true;
                }
            }
    
            int iLengthOfDataIn;
            while(baDataIn.length() > iMaxSize) {
                int iPosOfExlM = baDataIn.indexOf("!");
                QByteArray baTmp;
    
                if(iPosOfExlM != -1) {
                    baTmp = baDataIn.left(iPosOfExlM);
                    baDataIn = baDataIn.right(baDataIn.length() - (iPosOfExlM+1));
                    iLengthOfDataIn = baDataIn.length();
    
                    if(baTmp.length() >= iMinSize && baTmp.length() <= iMaxSize) {
                        this->displayValues(baTmp);
                    }
                }
            }
        }
        if(!bInvokedFirstTime) {
            bInvokedFirstTime = true;
            QByteArray baTmp = port.readAll();
        }
    }
    
    void MainWindow::createLayout() {
    
        QVBoxLayout * vBoxLayout = new QVBoxLayout();
        QFont f( "Arial", 30, QFont::Bold);
    
        for(int iItr = 0; iItr < strVoltages.length(); iItr++) {
            lDescription.append(new QLabel(strVoltages.at(iItr)));
            lDescription.last()->setFont(f);
            lDescription.last()->setFixedWidth(200);
    
            lLCDNumber.append(new QLCDNumber());
            lLCDNumber.last()->setFixedHeight(100);
    
            lIndicator.append(new QLabel());
            lIndicator.last()->setFixedWidth(100);
            lIndicator.last()->setFixedHeight(100);
            lIndicator.last()->setStyleSheet("QLabel { background-color : grey; }");
    
            QHBoxLayout *hBoxLayout = new QHBoxLayout();
            hBoxLayout->addWidget(lDescription.last());
            hBoxLayout->addWidget(lLCDNumber.last());
            hBoxLayout->addWidget(lIndicator.last());
    
            vBoxLayout->addLayout(hBoxLayout);
        }
    
        QPushButton *bReset = new QPushButton("Reset");
        vBoxLayout->addWidget(bReset);
        connect(bReset,SIGNAL(pressed()),this,SLOT(resetMeasurement()));
    
        QWidget *w = new QWidget();
        w->setLayout(vBoxLayout);
    
        setCentralWidget(w);
    }
    
    void MainWindow::resetMeasurement() {
        foreach(QLabel *lTmp, lIndicator) {
            lTmp->setStyleSheet("QLabel { background-color : grey; }");
        }
    }
    


  • if is working please mark this as solved from the menu... Many thanks


Log in to reply