我正在尝试用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;
}
}
答案 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;
}
}