GTKMM和boost.asio

时间:2017-06-22 02:55:43

标签: c++ boost gtkmm

我正在尝试用gtkmm编写一个简单的应用程序,它将显示从串行端口收到的值。我正在使用此处找到的AsyncSerial类 - https://github.com/fedetft/serial-port。这些类在命令行上对我来说都很好,但我无法让它们更新gtkmm中的标签。当我调用函数start_serial_read()时,lblMass接收一个空字符串,并且不输出任何内容。如果我在函数内停止程序并逐步执行该程序,则会为scaleReading分配正确的值,并输出读数。我缺少什么想法?我尝试使用glib :: sleep(50)给你时间来读取数据,但没有运气。感谢。

#include "FrmMain.h"
#include "AsyncSerial.h"
#include "BufferedAsyncSerial.h"
#include <iostream>
#include <boost/thread.hpp>
#include <string>
#include <gtkmm.h>

using namespace std;
using namespace Gtk;


FrmMain::FrmMain()
      : btnOk("OK"),
        btnCancel("Cancel"),
        labelSentStatus(""),
        lblMass("0.0"),
        timeout_value(1500), // 1500 ms = 1.5 seconds 
        vBox1(Gtk::ORIENTATION_VERTICAL),
        hBox1(Gtk::ORIENTATION_HORIZONTAL),
        hBox2(Gtk::ORIENTATION_HORIZONTAL),
        hBox3(Gtk::ORIENTATION_HORIZONTAL),
        hBox4(Gtk::ORIENTATION_HORIZONTAL)
{       
        set_title("Additives");
        set_border_width(10);

        hBox1.pack_start(lblMass, Gtk::PACK_SHRINK);    //pack mass reading into top box
        vBox1.pack_start(hBox1, Gtk::PACK_SHRINK);      //pack top box       
        vBox1.pack_start(hBox2, Gtk::PACK_SHRINK);      //pack empty space
        hBox3.pack_start(btnOk, Gtk::PACK_SHRINK);      //pack OK button into hBox3
        hBox3.pack_start(btnCancel, Gtk::PACK_SHRINK);      //pack cancel button into hBox3
        vBox1.pack_start(hBox3, Gtk::PACK_SHRINK);      //pack hbox3
        vBox1.pack_start(hBox4, Gtk::PACK_SHRINK);      //pack hbox3
        add(vBox1);

        btnOk.signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
    btnCancel.signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));
        sigc::slot<bool> timeoutSlot = sigc::mem_fun(*this, &FrmMain::start_serial_read);
        sigc::connection conn = Glib::signal_timeout().connect(timeoutSlot,timeout_value);
        show_all_children();  
}

void FrmMain::on_ok_button_clicked(){
    labelSentStatus.set_text("Sent");
}

void FrmMain::on_cancel_button_clicked(){
    labelSentStatus.set_text("");
}

bool FrmMain::start_serial_read()
{   
    try {
        BufferedAsyncSerial serial("/dev/ttyUSB0",4800);
        {
            //Return immediately. String is written *after* the function returns,
            //in a separate thread.
            //serial.writeString("Hello world\r\n");
            string scaleReading = serial.readStringUntil("\r");           
            lblMass.set_text(scaleReading);
            cout<<serial.readStringUntil("\r")<<endl;           
            serial.close();
            return true;
        }
    } catch(boost::system::system_error& e)
    {
        cout<<"Error: "<<e.what()<<endl;
        return true;
    }
}

1 个答案:

答案 0 :(得分:0)

我通过将timeout_value增加到2秒(timeout_value(2000))并在信号处理程序中使用Gtk :: sleep()函数来解决问题,以便为串行端口提供更多时间来获取读数。我之前尝试过的最多的是timeout_value(1500)和sleep(0.5),结果证明它太短了一段时间。这是更新的代码:

/*
 * FrmMain.cpp
 *
 *  Created on: Jun 17, 2017
 *      Author: tim
 */

#include "FrmMain.h"
#include "AsyncSerial.h"
#include "BufferedAsyncSerial.h"
#include <iostream>
#include <boost/thread.hpp>
#include <string>
#include <gtkmm.h>
#include <typeinfo>
using namespace std;
using namespace Gtk;


FrmMain::FrmMain()
      : btnOk("OK"),
        btnCancel("Cancel"),
        labelSentStatus(""),
        lblMass("0.0"),
        timeout_value(2000), // 1500 ms = 1.5 seconds 
        vBox1(Gtk::ORIENTATION_VERTICAL),
        hBox1(Gtk::ORIENTATION_HORIZONTAL),
        hBox2(Gtk::ORIENTATION_HORIZONTAL),
        hBox3(Gtk::ORIENTATION_HORIZONTAL),
        hBox4(Gtk::ORIENTATION_HORIZONTAL)

{       
        set_title("Additives");
        set_border_width(10);
        hBox1.pack_start(lblMass, Gtk::PACK_SHRINK);    //pack mass reading into top box
        vBox1.pack_start(hBox1, Gtk::PACK_SHRINK);      //pack top box       
        vBox1.pack_start(hBox2, Gtk::PACK_SHRINK);      //pack empty space
        hBox3.pack_start(btnOk, Gtk::PACK_SHRINK);      //pack OK button into hBox3
        hBox3.pack_start(btnCancel, Gtk::PACK_SHRINK);      //pack cancel button into hBox3
        vBox1.pack_start(hBox3, Gtk::PACK_SHRINK);      //pack hbox3
        vBox1.pack_start(hBox4, Gtk::PACK_SHRINK);      //pack hbox3
        add(vBox1);
        btnOk.signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
    btnCancel.signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));
        sigc::slot<bool> timeoutSlot = sigc::mem_fun(*this, &FrmMain::start_serial_read);
        Glib::signal_timeout().connect(timeoutSlot,timeout_value);
        show_all_children();  
}

FrmMain::~FrmMain(){

}

void FrmMain::on_ok_button_clicked(){
    labelSentStatus.set_text("Sent");
}

void FrmMain::on_cancel_button_clicked(){
    labelSentStatus.set_text("");
}

bool FrmMain::start_serial_read()
{   
    try {
        BufferedAsyncSerial serial("/dev/ttyUSB0",4800);
        sleep(1);
        //boost::this_thread::sleep(boost::posix_time::seconds(2));
        //Return immediately. String is written *after* the function returns,
        //in a separate thread.
        //serial.writeString("Hello world\r\n");
        string scaleReading = serial.readStringUntil("\r");   
        lblMass.set_text(scaleReading);
        cout<<scaleReading("\r")<<endl;           
        serial.close();
        return true;

    } catch(boost::system::system_error& e)
    {
        cout<<"Error: "<<e.what()<<endl;
        return true;
    }
}