zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Ubuntu下图形界面串口工具CuteCom的安装和升级

2023-03-07 09:38:57 时间

串口的图形界面化工具在Windows下很多, 但是在Linux下可选择的就很少, CuteCom 是相对比较好用的一款了. Ubuntu20.04默认安装的是0.30.3, 这是一个比较早的版本, 最新的版本是0.51.0, 如果需要自定义RTS电平高低, 例如连接W801这样RESET连接了RTS的开发板, 就需要升级到最新版.

安装和更新到最新版本

默认安装

在Ubuntu下使用apt可以直接安装

sudo apt install cutecom

这样安装的是0.30.3版本

CuteCom的项目地址

如果需要使用最新版本, 需要自行编译

现在最新的代码在Gitlab, 当前版本为0.51.0

环境准备

CuteCom并未提供预编译的安装包, 所以需要自己本地编译, 本地编译需要安装Qt的开发环境

apt install apt-transport-https git dh-make build-essential autoconf autotools-dev qt5-default libssl-dev qt5keychain-dev devscripts

因为CuteCom用到了Qtserial, 所以还需要安装

apt install libqt5serialport5-dev

Ubuntu22.04

sudo apt install qtbase5-dev qt5-qmake cmake dh-make build-essential autoconf autotools-dev libqt5serialport5-dev

下载和编译

git clone https://gitlab.com/cutecom/cutecom.git
cd cuteCom
cmake .
make

编译完成后在同一目录下, 可以看到cutecom的可执行文件

替换本机安装的CuteCom

# 确认cutecom的位置
whereis cutecom
# 本例是在/usr/bin
cd /usr/bin
mv cutecom cutecom.0.30.3
mv ~/cutecom/cutecom .

对于使用Qt Creator的用户, 在cmake之前, Qt Creator不能直接编译Cutecom项目, 在cmake之后, Qt Creator就可以在IDE里直接编译了.

新版本中的RTS控制功能

在设置中, 如果选择了Flow Control为NONE, 在面板上会增加两个勾选框选项: RTS和DTR. 使用中, 勾选RTS会拉低电平, 不勾选则会使RTS保持低电平, 在连接W801开发板时, 需要取消勾选. 如果在W801开发板上已经给RESET和GND之间加焊了电容, 可以在开发板运行中打开和关闭串口而不会导致开发板重启.

在连接状态中, 可以通过勾选/取消勾选实时控制RTS的电平状态.

Cutecom的代码解读

CuteCom的是比较标准的Qt项目

项目文件 CuteCom.pro

项目文件中定义了项目包含的.cpp, .h文件, .ui后缀的界面文件, 资源文件resources.qrc
DISTFILES设置的是qt.astylerc, 这个似乎是代码格式插件Artistic Style的配置

启动入口 main.cpp

这里设置程序名称, 可以看到已经使用了QCoreApplication::translate(, 可以支持多国化, 但是现在还没有其它语言的资源
然后就是初始化MainWindow, show()启动

主窗口 mainwindow.cpp 和 mainwindow.h

  • 主界面在mainwidnow.ui中定义, 最外层使用的是QMainWindow控件
  • 主界面上需要包含的元素, 其它的界面元素类, 在mainwindow.h中声明, 在mainwindow.cpp中创建并加入到对应的QWidget中
  • mainwindow.cpp 通过 mainwindows.h 关联ui ui_mainwindow.h
  • ui_mainwindow.h 是由ui文件生成的, 其中不仅声明了界面元素, 还定义了 setupUi() 方法, 里面有具体的界面展示实现, 以及 retranslateUi() 方法, 用于对界面元素的多国化展示
    • setupUi() 在 mainwindow.cpp 的构建方法中调用.
MainWindow::MainWindow(QWidget *parent, const QString &session)
    : QMainWindow(parent)
    , m_device(new QSerialPort(this))
    , m_deviceState(DEVICE_CLOSED)
    , m_progress(nullptr)
    , m_sz(nullptr)
    , m_previousChar('\0')
    , m_command_history_model(nullptr)
    , m_ctrlCharactersPopup(nullptr)
    , m_keyRepeatTimer(this)
    , m_keyCode('\0')
    , m_cmdBufIndex(0)
    , m_reconnectTimer(this)
{
    QCoreApplication::setOrganizationName(QStringLiteral("CuteCom"));
    // setting it to CuteCom5 will prevent the original CuteCom's settings file
    // to be overwritten
    QCoreApplication::setApplicationName(QStringLiteral("CuteCom5"));
    QCoreApplication::setApplicationVersion(QStringLiteral("%1").arg(CuteCom_VERSION));
    //    qRegisterMetaType<Settings::LineTerminator>();

    setupUi(this);

    m_bt_sendfile->setEnabled(false);
    m_command_history->setEnabled(false);
    m_command_history->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection);

    m_lb_logfile->setStyleSheet(" QLabel:hover{color: blue;} ");
    ...
  • retranslateUi() 方法未被调用
  • 在 qmainwindow.h 中, 使用QT_CONFIG()宏定义根据编译环境的Qt是否包含某个特性而加入对应的声明, 不需要开发者关心
/*
    The QT_CONFIG macro implements a safe compile time check for features of Qt.
    Features can be in three states:
        0 or undefined: This will lead to a compile error when testing for it
        -1: The feature is not available
        1: The feature is available
*/
#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)
  • 加入ControlPanel
controlPanel = new ControlPanel(this->centralWidget(), m_settings);
  • 加入状态栏的方式和ControlPanel的方式不一样
// setup status bar with initial infromation
m_device_statusbar = new StatusBar(this);
m_device_statusbar->sessionChanged(m_settings->getCurrentSession());
this->statusBar()->addWidget(m_device_statusbar);

mainwindow 中的用户动作, 一部分是通过 connect() 实现关联, 另一部分是通过 eventFilter(), 通过控件的 installEventFilter() 方法, 将 eventFilter() 中定义的逻辑关联到当前控件上.

mainwindow 中, 使用 signal 关联 controlpanl 传递来的连接/关闭串口的操作, 调用当前类下的连接/关闭方法

connect(controlPanel, &ControlPanel::openDeviceClicked, this, &MainWindow::openDevice);
connect(controlPanel, &ControlPanel::closeDeviceClicked, this, &MainWindow::closeDevice);

对RTS和DTR的控制

  • 处理方法为void MainWindow::setRTSLineState(int checked), 这个方法里面的m_device就是一个QSerialPort设备, 对应的setRequestToSend(true)方法会将RTS电平拉低(有些硬件的电平是相反的)
void MainWindow::setRTSLineState(int checked)
{
    if ((nullptr != m_device) && (true == m_device->isOpen())) {
        if (Qt::CheckState::Checked == static_cast<Qt::CheckState>(checked)) {
            m_device->setRequestToSend(true);
        } else {
            m_device->setRequestToSend(false);
        }
    }
}
  • 消息绑定在mainwindow.cpp里, connect(controlPanel->m_rts_line, &QCheckBox::stateChanged, this, &MainWindow::setRTSLineState);

Settings控制面板的收起和打开

  • 信号关联connect(m_panel_settings, &QTabWidget::tabBarClicked, this, &ControlPanel::tabClicked);
  • 对应的tabClicked是在controlpanel.h中定义的
// slots
void tabClicked(int i)
{
    Q_UNUSED(i);
    toggleMenu();
}
  • toogleMenu()方法里实现了控制面板的收起和打开
void ControlPanel::toggleMenu()
{
    // Create animation
    QPropertyAnimation *animation = new QPropertyAnimation(this, "pos");
    QPoint endPos = m_menuVisible ? QPoint(m_x, m_y) : QPoint(m_x, -13);
    //    qDebug() << m_menuVisible << endPos;
    animation->setStartValue(pos());
    animation->setEndValue(endPos);
    animation->start();
    if (m_menuVisible) {
        m_panel_settings->setTabIcon(0, showIcon);
        m_menuVisible = false;
    } else {
        m_panel_settings->setTabIcon(0, hideIcon);
        m_menuVisible = true;
        m_combo_Baud->setFocus();
    }
}

问题

如果使用Ubuntu20.04自带的qt库(5.12.x版本)编译, 控制面板界面的那些输入和下拉控件高度在HDPI屏幕下会特别小, 如果使用Qt Creator的qt库(5.14.x版本)编译, 这个高度就是正常的.