Ubuntu下圖形界面串口工具CuteCom的安裝和升級


串口的圖形界面化工具在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版本)編譯, 這個高度就是正常的.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM