路由設備管理軟體開發總結
需求概要
該軟體其目的為一個網關設備提供遠程管理GUI,設備系統為Linux系統,原生系統只能提供命令列操作,對于一般用戶不太友好,所以需要開發一款簡單的具有用戶界面的軟體,
軟體需實作以下功能:
- 遠程連接設備;
- IP 配置;
- 防火墻配置;
- 路由(route)配置;
- 其他(如VPN)服務配置;
- 實作工具ping、telnet并運行在遠程設備端,
需求分析
除了上述功能需求以外,需要考慮軟體面向的用戶,是普通用戶,他們對這些路由、防火墻等概念和原理并不完全了解,因此在配置程序中難免會遇到困難,甚至一個錯誤的配置會讓系統陷入崩潰,當然這也是系統設計應該考慮的問題,在此,本設備管理軟體是面向用戶的最前端,也是系統保護的第一道防線,因此不得不擔負起雙重責任:
- 提供簡單易用的用戶向導,引導非專業用戶完成陌生系統的配置;
- 提供標準的輸入方式,限制用戶可能的錯誤操作,實作保護系統,
以上是界面互動設計的原則,提供準確的提示資訊,指參考戶操作,盡量限制用戶的操作自由度,比如引數盡量格式化,IP地址輸入框利用Regex進行格式限定,引數限制輸入范圍;提供默認建議設定等,
技術方案
采用Qt5.9,可以實作跨平臺;
遠程鏈接采用ssh 鏈接,采用現有的libssh庫,關于libssh庫的下載和編譯見下文,
開發環境搭建
- 其中libssh下載,下載好后需要自行編譯,編譯通過
mkdir build cd build cmake .. make - Windows 端可以通過以下命令安裝:
vcpkg install libssh - 其中vcpkg 是Microsoft 為windows 提供的一個c/c++ 的開源包管理工具,見 github,
- 需要編譯好的ssh.lib、ssh.dll和ssh.h 可以留言,
踩坑記錄
- 使用QTextEdit 作為用戶操作日志顯示,如下代碼
class ToolDialog:public QDialog{
public:
void showLog()
{
QSting msg;
while(receive(msg))
{
ui->textEdit->append(msg);
}
}
};
是從遠程回圈接收命令列訊息,如執行ping命令后的中端資訊,以上代碼片段是在主回圈中,有朋友可能會說這顯然不行,其實我的這段代碼是在一個彈出的模態對話框中,不介意阻塞其他界面的回應,可惜的是,還真不行,上述代碼并不能將遠程終端資訊及時顯示到界面中,
分析其原因,可能是上述在主回圈中,while 回圈占據了cpu 時間,阻塞了GUI 的事件回圈,所以界面無法顯示日志資訊,可能你會想到添加sleep 函式強制讓出cpu,其實也是無濟于事,因為讓出的cpu 時間也是讓給了其他執行緒,GUI還是依然無法得到cpu 時間,
那么,就只能就將回圈移入到作業執行緒中,Qt提供了方便的處理辦法,創建一個作業執行緒接收遠程設備訊息,將while 代碼段也就移入執行緒中的doWork 方法,然后利用信號發送出來,在ToolDialog中接收信號并顯示到日志控制元件textEdit 中,這下應該可以了吧?
//Worker
class Worker:public QObject
{
void Worker(QObject *parent):QObject(parent){}
void doWork()
{
QSting msg;
while(receive(msg))
{
sendMsg(msg);
}
}
signals:
void sendMsg(const QString&msg);
...
};
//GUI
class ToolDialog:public QDialog{
public:
ToolDialog(QWidget*parent){
m_thread = std::make_shared<Qthread>(this);
m_worker = std::make_shared<Qthread>(this);
m_worker->moveToThread(m_thread);
connect(m_threrad, &QThread::started, m_worker, &Worker::doWork);
connect(m_worker, &Worker::sendMsg, this, [=](const QString &msg) {
ui->textEdit->append(msg.trimmed());
}, Qt::QueuedConnection);
m_thread->start();
}
private:
std::shared_ptr<QThread>m_thread;
std::shared_ptr<Worker>m_worker;
};
其實不然,又不行,界面無任何回應,除錯跟蹤發現執行緒就未啟動,m_thread->start() 就是啟動執行緒的呀,觀察輸出視窗提示moveToThread執行失敗,難道使用方法錯誤,只能查看幫助檔案,檔案中這樣寫道:Changes the thread affinity for this object and its children. The object cannot be moved if it has a parent. Event processing will continue in the targetThread. 找到答案了,也就是worker在轉移到Thread 之前不能有parent,所以錯誤在于
m_worker = std::make_shared<Qthread>(this);
修改為:
m_worker = std::make_shared<Qthread>();

測驗發現果然如此,
4. 在QTextEidt 為右鍵選單添加快捷鍵時,修改多此代碼,快捷鍵都無效,
void LogWidget::contextMenuEvent(QContextMenuEvent *event)
{
QMenu *menu = createStandardContextMenu();
QAction *action = menu->addAction(tr("Clear"));
action->setShortcut(QKeySequence::Delete);
//action->setShortcutContext(Qt::ApplicationShortcut);
connect(action,&QAction::triggered,this,&QTextEdit::clear);
menu->exec(event->globalPos());
delete menu;
}
界面顯示快捷鍵為Del,但是按鍵盤的Delete 鍵,無任務反應,滑鼠點擊可以作業,查看各大網站說是Qt 的bug,感謝有知道讀者幫忙糾正,

經驗總結
- 在開發前做好流程設計;
- 代碼層次分明,各干其事情;
- 開發中盡量使用English,如果需要中文,然后再做翻譯,需要翻譯的文本使用 tr(""),
翻譯程序:- 跟新*.ts 檔案,獲取需要翻譯的文本資訊,

- 使用Qt Linguist 修改ts 檔案,

- 最后使用發布翻譯(lrelease)
- 添加代碼,翻譯完成,
QTranslator translator; translator.load(":/*_zh_CN.qm"); qApp->installTranslator(&translator); - 跟新*.ts 檔案,獲取需要翻譯的文本資訊,
- Windows 平臺安裝包制作工具Inno Setup,
暫時就寫到這里,歡迎評論區留言!
感謝!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/299162.html
標籤:其他
上一篇:常見面試題
下一篇:git版本控制工具
