Qt Serial Port Initialization



  • Hello all!
    I am having issues understanding and adapting the Qt asynchronous example. I want to make a popup window that requires the user to connect to an active serial port before continuing. I like the look of the drop down menu of available com ports but I can't seem to understand the code. I keep running into needing to go from QList to QStringList but I don't know if I am going about this correctly. I am confined to just code as far as I know as I am trying to implement the ArcGIS Runtime Enviroment but it seems to not play well with others. (Probably because I am no the brightest at both Qt and Arc). Any help would be appreciated. Any help would be appreciated! Thank you for your time!


  • Lifetime Qt Champion

    Hi,

    Which example are you referring to ?

    On a side note, did you saw that ArcGIS has a "Runtime SDK for Qt":https://developers.arcgis.com/qt/ ?



  • The QSerialPort class has an available serial ports:

    @
    QSerialPortInfo::availablePorts()
    @

    It returns:

    @QList<QSerialPortInfo>@

    With that QList you get get serial port info... this is sorta old school I guess the way it iterates but it works:

    @ QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
    for( int c=0; c<ports.count(); c++ )
    {
    qDebug() << ports.at(c).portName() << " - " << ports.at(c).description();
    }@

    You could populate a list with this if you wanted and have the user select from that list. For example on a dialog you could have a list and add items to the list:
    @
    ui->portList->addItem( ports.at(c).portName() );
    @

    @ports.at(c).portName() @

    is the name you need to pass to QSerialPort to open the port.



  • Sorry I can't add anything to ArcGIS... I was thinking you needed to know how to find ports.



  • Thanks for the replies!

    The example I was mentioning was the Qt Serial Asynchronous example in regards to the settings part of the code as I was trying to make a popup window that required the user to select an available com port to continue.

    As to the ArcGIS developer API, I am using the link that you linked above but the examples they provide are difficult to understand and use very few functions that relate without their sample files. This is making it very difficult to learn Qt and ArcGIS at the same time. Overall I'd like to section my GUI into data returned and a map but that's for future me and another thread to figure out.

    Using the serial data provided above I was able to write this code:

    @ bool ok;
    QStringList availablePorts;
    QList<QSerialPortInfo> com_ports = QSerialPortInfo::availablePorts();
    for(int i=0;i<com_ports.count();i++)
    {
    //qDebug()<<com_ports.at(i).portName()<<"-"<<com_ports.at(i).description();
    availablePorts<<(com_ports.at(i).portName() );
    }

    QInputDialog::getItem(this, tr("COM #"),
    tr("COM Port:"),availablePorts , 0, false, &ok);@

    I know it is not the most pretty code right now. I am trying to figure out the popup part right now of the dialog box. I know that I need a ___.show(); at some point but not really sure where. Also having this code seems to crash my overall project if anyone has any thoughts on that.



  • Hi,

    Are you saying that if you comment out the entire block above you don't get a crash?

    I'd try commenting out bits and pieces till you find it. I don't offhand see anything that should cause a crash but without seeing how you are using this something could be causing it.

    On dialogs you can either show() (nonmodal) or exec() which will be modal.

    The process I use is to have QList member of your dialog and have either as part of the constructor code to copy in your availablePorts QStringList,

    OR

    You could simply as part of your dialog constructor do all the serial port searching and QList filling then.

    If you think the number of ports might change you have a couple of options. After you new up a Dialog (if you do the serial port code in the dialog constructor) you'd need to delete it, then new it again to get a new list of ports.

    Alternatively you can catch the show signal and recreate your list of ports then.

    Let me know if you need help with a dialog. I can send over an example if you'd like. It helps me to do this stuff as I am still new as well. I have a dialog that I put help into which would be based on the same idea.



  • Thank you for your assistance!

    This is the message I get when I try to run it:
    @Starting C:\Qt\Projects\build-Gui-Desktop_Qt_5_4_0_MSVC2012_OpenGL_32bit-Debug\debug\Gui.exe...
    The program has unexpectedly finished.
    C:\Qt\Projects\build-Gui-Desktop_Qt_5_4_0_MSVC2012_OpenGL_32bit-Debug\debug\Gui.exe crashed@

    Could it have anything to do with ArcGIS's map declaration as a central widget in the same file?

    I was hoping to just have the dialog box show up upon start up and not allow the code to progress until a port is selected. It would probably be good to update the ports every few seconds if the user hasn't plugged a serial interface in yet.

    I would greatly appreciate any code you are willing to share with me! Thank you so much for the offer! You sir are amazing!


  • Lifetime Qt Champion

    You should show your complete code otherwise it's pretty much Crystal Ball debugging.

    You should have a backtrace telling you where the crash happened.

    In between, where are you ArcGIS library installed ? Can it's dlls be found when you start your program ?



  • The code is a little large and exceeds the 6000 characters quite easy so I will do what I can.

    "https://drive.google.com/folderview?id=0B92HcF-BSQBpYV8zSXV3dzdhT3M&usp=sharing"

    This is the best way I could think to share the files. If you have an alternative please let me know.

    @ // set to openGL rendering
    EsriRuntimeQt::ArcGISRuntime::setRenderEngine(EsriRuntimeQt::RenderEngine::OpenGL);

    // sets central window spot for map
    m_mapGraphicsView = EsriRuntimeQt::MapGraphicsView::create(m_map, this);
    setCentralWidget(m_mapGraphicsView);
    //set wrap around
    m_map.setWrapAroundEnabled(true);
    
    // show Esri logo by default
    m_map.setEsriLogoVisible(false);
    
    //add map
    QString path = EsriRuntimeQt::ArcGISRuntime::installDirectory();
    path.append("/sdk/samples/data");
    QDir dataDir(path); // using QDir to convert to correct file separator
    QString pathSampleData = dataDir.path() + QDir::separator();
    //// ArcGIS Online Tiled Basemap Layer
    m_tiledServiceLayer = EsriRuntimeQt::ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
    m_map.addLayer(m_tiledServiceLayer);
    

    @
    This is the code that follows the serial code. I have compiled and run it many times and it works. Thanks for your time guys.

    P.S. Sorry for the terrible code



  • So I was able to fumble around with the code enough that I got the popup window to display how I wanted. Now I just need to connect the slots and signals code to the connect button and com port name. any ideas on querying the string on click of the connect? The code I have so far is:
    @ QMainWindow *window = new QMainWindow();
    window->setWindowTitle(QString::fromUtf8("Select Com Port"));
    window->resize(225,75);
    QWidget *centralWidget = new QWidget(window);
    QHBoxLayout layout = new QHBoxLayout();
    centralWidget->setLayout(layout);
    Serial
    comboBox =new Serial (centralWidget);
    QPushButton *connectButton = new QPushButton("Connect");
    QList<QSerialPortInfo> com_ports = QSerialPortInfo::availablePorts();
    for(int i=0;i<com_ports.count();i++)
    {
    qDebug()<<com_ports.at(i).portName()<<"-"<<com_ports.at(i).description();
    comboBox->addItem(com_ports.at(i).portName() );
    }
    layout->addWidget(comboBox);
    layout->addWidget(connectButton);
    window->setCentralWidget(centralWidget);
    window->show();@

    and:
    @ Serial(QWidget* parent):QComboBox(parent)
    {
    this->setParent(parent);
    connect(this , SIGNAL(clicked(QString)),this,SLOT(handleSelectionChanged(QString)));
    }
    QStringList selectedPort;@


  • Lifetime Qt Champion

    You should rather create a custom QDialog for that and give it a getter that will return the selected value of the combo box



  • How would I go about that?


  • Lifetime Qt Champion

    Very brief version

    @
    class SerialPortSelectionDialog : public QDialog {
    // Usual stuff
    QString selectedPort() const { return _serialPortChoiceComboBox->currentText(); }

    private:
    QComboBox *_serialPortChoiceComboBox;
    };
    @

    And the appropriate place in your code:
    @
    SerialPortSelectionDialog selectionDialog;
    selectionDialog.exec();
    QString serialPort = selectionDialog.selectedPort();
    // setup your serial port
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.