Loading... # 引言 termux-x11 模式下支持的软件很少,但是好在有xfreerdp,这样的话,可以通过命令行来实现rdp的连接,但是记命令记不住,可视化的工具也没有,如果轻量使用,可以试试`https://github.com/wyllianbs/xfreerdp-gui/`,但是我为什么没有用这个呢?因为`yad`需要安装,apt尝试安装,不存在,源码编译yad又各种问题,后来又尝试`zenity`效果还不错,但是并不是我想要的, # 方案1--zenity ```bash #!/bin/bash # 获取用户输入的主要信息 USER_INPUT=$(zenity --forms \ --title="Remote Desktop Connection" \ --text="Enter the following details:" \ --separator="," \ --add-entry="Server Address" \ --add-entry="Username" \ --add-password="Password" \ --add-entry="Resolution (e.g., 1920x1080)" \ --add-combo="Color Depth (bpp)" --combo-values="8|16|24|32" \ --add-combo="Network" --combo-values="modem|broadband-low|broadband|broadband-high|wan|lan" \ --add-combo="Audio Mode" --combo-values="off|local|remote" \ --height=300) # 检查用户是否取消输入 if [ $? -ne 0 ]; then exit 1 fi # 解析用户输入 IFS=',' read -r SERVER USERNAME PASSWORD RESOLUTION BPP NETWORK AUDIO_MODE <<< "$USER_INPUT" # 获取用户输入的复选框选项 CHECKBOX_INPUT=$(zenity --list \ --title="Advanced Options" \ --text="Select the advanced options:" \ --separator="," \ --checklist \ --column="Select" --column="Option" \ TRUE "Dynamic Resolution" \ TRUE "Compression" \ TRUE "Glyph Cache" \ TRUE "Bitmap Cache" \ TRUE "Async Input" \ TRUE "Async Update" \ --height=300) # 检查用户是否取消输入 if [ $? -ne 0 ]; then exit 1 fi # 初始化选项参数 OPTIONS_ARRAY=() # 添加选项参数 [[ $CHECKBOX_INPUT =~ "Dynamic Resolution" ]] && OPTIONS_ARRAY+=("/dynamic-resolution") [[ $CHECKBOX_INPUT =~ "Compression" ]] && OPTIONS_ARRAY+=("/compression") [[ $CHECKBOX_INPUT =~ "Glyph Cache" ]] && OPTIONS_ARRAY+=("/gdi:hw") [[ $CHECKBOX_INPUT =~ "Bitmap Cache" ]] && OPTIONS_ARRAY+=("/bitmap-cache") [[ $CHECKBOX_INPUT =~ "Async Input" ]] && OPTIONS_ARRAY+=("/async-input") [[ $CHECKBOX_INPUT =~ "Async Update" ]] && OPTIONS_ARRAY+=("/async-update") # 生成完整的 xfreerdp 命令 COMMAND="xfreerdp /v:$SERVER /u:$USERNAME /p:$PASSWORD /size:$RESOLUTION /bpp:$BPP /network:$NETWORK ${OPTIONS_ARRAY[*]} /audio-mode:$AUDIO_MODE" # 执行 xfreerdp 命令 eval $COMMAND ``` ![image.png](https://www.zunmx.top/usr/uploads/2024/07/2233297880.png) ![image.png](https://www.zunmx.top/usr/uploads/2024/07/332262857.png) # 方案2--qt ![image.png](https://www.zunmx.top/usr/uploads/2024/07/130456571.png) ![image.png](https://www.zunmx.top/usr/uploads/2024/07/2377654518.png) ![image.png](https://www.zunmx.top/usr/uploads/2024/07/778619985.png) ## UI代码 ```xml <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>421</width> <height>341</height> </rect> </property> <widget class="QWidget" name="centralwidget"> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> <number>0</number> </property> <widget class="QWidget" name="tab"> <attribute name="title"> <string>Normal Options</string> </attribute> <layout class="QGridLayout" name="gridLayout_2"> <item row="0" column="0"> <widget class="QScrollArea" name="scrollArea_2"> <property name="widgetResizable"> <bool>true</bool> </property> <widget class="QWidget" name="scrollAreaWidgetContents_2"> <property name="geometry"> <rect> <x>0</x> <y>-20</y> <width>365</width> <height>262</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_5"> <item row="0" column="0" rowspan="2" colspan="2"> <layout class="QGridLayout" name="gridLayout"> <item row="5" column="1" colspan="3"> <widget class="QComboBox" name="resolution_comboBox"> <item> <property name="text"> <string>800x600</string> </property> </item> <item> <property name="text"> <string>1024x760</string> </property> </item> <item> <property name="text"> <string>1280x600</string> </property> </item> <item> <property name="text"> <string>1360x768</string> </property> </item> <item> <property name="text"> <string>1440x900</string> </property> </item> <item> <property name="text"> <string>1600x900</string> </property> </item> <item> <property name="text"> <string>1920x1080</string> </property> </item> <item> <property name="text"> <string>1920x1200</string> </property> </item> </widget> </item> <item row="7" column="1" colspan="3"> <widget class="QComboBox" name="network_comboBox"> <item> <property name="text"> <string>auto</string> </property> </item> <item> <property name="text"> <string>modem</string> </property> </item> <item> <property name="text"> <string>broadband-low</string> </property> </item> <item> <property name="text"> <string>broadband</string> </property> </item> <item> <property name="text"> <string>broadband-high</string> </property> </item> <item> <property name="text"> <string>wan</string> </property> </item> <item> <property name="text"> <string>lan</string> </property> </item> </widget> </item> <item row="5" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> <string>Resolution</string> </property> </widget> </item> <item row="8" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> <string>Audio Mode</string> </property> </widget> </item> <item row="8" column="1" colspan="3"> <widget class="QComboBox" name="audio_comboBox"> <item> <property name="text"> <string>off</string> </property> </item> <item> <property name="text"> <string>local</string> </property> </item> <item> <property name="text"> <string>remote</string> </property> </item> </widget> </item> <item row="6" column="0"> <widget class="QLabel" name="label_5"> <property name="text"> <string>Color Depth(bpp)</string> </property> </widget> </item> <item row="1" column="0"> <widget class="QLabel" name="label"> <property name="text"> <string>Host</string> </property> </widget> </item> <item row="7" column="0"> <widget class="QLabel" name="label_6"> <property name="text"> <string>Network</string> </property> </widget> </item> <item row="4" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> <string>Password</string> </property> </widget> </item> <item row="3" column="1" colspan="3"> <widget class="QLineEdit" name="username_text"/> </item> <item row="1" column="1"> <widget class="QLineEdit" name="host_text"/> </item> <item row="1" column="3"> <widget class="QLineEdit" name="port_text"> <property name="maximumSize"> <size> <width>60</width> <height>16777215</height> </size> </property> <property name="text"> <string>3389</string> </property> </widget> </item> <item row="3" column="0"> <widget class="QLabel" name="label_2"> <property name="text"> <string>UserName</string> </property> </widget> </item> <item row="1" column="2"> <widget class="QLabel" name="label_18"> <property name="text"> <string>:</string> </property> </widget> </item> <item row="4" column="1" colspan="3"> <widget class="QLineEdit" name="password_text"/> </item> <item row="6" column="1" colspan="3"> <widget class="QComboBox" name="bpp_comboBox"> <item> <property name="text"> <string>8</string> </property> </item> <item> <property name="text"> <string>16</string> </property> </item> <item> <property name="text"> <string>24</string> </property> </item> <item> <property name="text"> <string>32</string> </property> </item> </widget> </item> <item row="2" column="0"> <widget class="QLabel" name="label_19"> <property name="text"> <string>Domain</string> </property> </widget> </item> <item row="2" column="1" colspan="3"> <widget class="QLineEdit" name="domain_text"/> </item> </layout> </item> </layout> </widget> </widget> </item> </layout> </widget> <widget class="QWidget" name="tab_2"> <attribute name="title"> <string>Advanced Options</string> </attribute> <layout class="QGridLayout" name="gridLayout_3"> <item row="0" column="0"> <widget class="QScrollArea" name="scrollArea"> <property name="widgetResizable"> <bool>true</bool> </property> <widget class="QWidget" name="scrollAreaWidgetContents"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>365</width> <height>365</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_4"> <item row="1" column="0"> <layout class="QFormLayout" name="formLayout"> <item row="1" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> <string>Dynamic Resolution</string> </property> </widget> </item> <item row="2" column="0"> <widget class="QLabel" name="label_9"> <property name="text"> <string>Compression</string> </property> </widget> </item> <item row="3" column="0"> <widget class="QLabel" name="label_10"> <property name="text"> <string>Glyph Cache</string> </property> </widget> </item> <item row="4" column="0"> <widget class="QLabel" name="label_11"> <property name="text"> <string>Bitmap Cache</string> </property> </widget> </item> <item row="5" column="0"> <widget class="QLabel" name="label_12"> <property name="text"> <string>Async Input</string> </property> </widget> </item> <item row="6" column="0"> <widget class="QLabel" name="label_13"> <property name="text"> <string>Async Update</string> </property> </widget> </item> <item row="1" column="1"> <widget class="QCheckBox" name="dynamic_resolution_box"> <property name="text"> <string>Enable</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> <item row="2" column="1"> <widget class="QCheckBox" name="compression_box"> <property name="text"> <string>Enable</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> <item row="3" column="1"> <widget class="QCheckBox" name="glyph_cache_box"> <property name="text"> <string>Enable</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> <item row="4" column="1"> <widget class="QCheckBox" name="bitmap_cache_box"> <property name="text"> <string>Enable</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> <item row="5" column="1"> <widget class="QCheckBox" name="async_input_box"> <property name="text"> <string>Enable</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> <item row="6" column="1"> <widget class="QCheckBox" name="async_update_box"> <property name="text"> <string>Enable</string> </property> <property name="checked"> <bool>true</bool> </property> </widget> </item> <item row="8" column="0"> <widget class="QLabel" name="label_14"> <property name="text"> <string>Share Direcory</string> </property> </widget> </item> <item row="8" column="1"> <widget class="QLineEdit" name="share_directory_text"/> </item> <item row="7" column="0"> <widget class="QLabel" name="label_15"> <property name="text"> <string>Shared Directory Name</string> </property> </widget> </item> <item row="7" column="1"> <widget class="QLineEdit" name="shared_directory_name_text"> <property name="text"> <string>Shared</string> </property> </widget> </item> <item row="0" column="0"> <widget class="QLabel" name="label_16"> <property name="text"> <string>Full Screen</string> </property> </widget> </item> <item row="0" column="1"> <widget class="QCheckBox" name="full_screen_box"> <property name="text"> <string>Enable</string> </property> </widget> </item> <item row="9" column="0"> <widget class="QLabel" name="label_17"> <property name="text"> <string>Other Options</string> </property> </widget> </item> <item row="9" column="1"> <widget class="QTextEdit" name="other_options_text"> <property name="minimumSize"> <size> <width>0</width> <height>80</height> </size> </property> </widget> </item> </layout> </item> </layout> </widget> </widget> </item> </layout> </widget> <widget class="QWidget" name="tab_3"> <attribute name="title"> <string>Help</string> </attribute> <layout class="QGridLayout" name="gridLayout_6"> <item row="0" column="0"> <widget class="QTextBrowser" name="textBrowser"/> </item> </layout> </widget> </widget> </item> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>40</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QPushButton" name="cancel_button"> <property name="text"> <string>Cancel</string> </property> </widget> </item> <item> <widget class="QPushButton" name="connect_button"> <property name="text"> <string>Connect</string> </property> </widget> </item> </layout> </item> </layout> </widget> </widget> <tabstops> <tabstop>host_text</tabstop> <tabstop>port_text</tabstop> <tabstop>domain_text</tabstop> <tabstop>username_text</tabstop> <tabstop>password_text</tabstop> <tabstop>resolution_comboBox</tabstop> <tabstop>bpp_comboBox</tabstop> <tabstop>network_comboBox</tabstop> <tabstop>audio_comboBox</tabstop> <tabstop>full_screen_box</tabstop> <tabstop>dynamic_resolution_box</tabstop> <tabstop>compression_box</tabstop> <tabstop>glyph_cache_box</tabstop> <tabstop>bitmap_cache_box</tabstop> <tabstop>async_input_box</tabstop> <tabstop>async_update_box</tabstop> <tabstop>shared_directory_name_text</tabstop> <tabstop>share_directory_text</tabstop> <tabstop>other_options_text</tabstop> <tabstop>connect_button</tabstop> <tabstop>cancel_button</tabstop> <tabstop>scrollArea</tabstop> <tabstop>textBrowser</tabstop> <tabstop>scrollArea_2</tabstop> <tabstop>tabWidget</tabstop> </tabstops> <resources/> <connections/> </ui> ``` ## mainwindow.h ```cpp #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); void GetDefault(); private slots: void on_cancel_button_clicked(); void on_connect_button_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H ``` ## mainwindow.cpp ```c++ #include "mainwindow.h" #include "ui_mainwindow.h" #include <QApplication> #include <QScreen> #include <QMessageBox> #include <QDebug> #include <QProcess> void MainWindow::GetDefault(){ QScreen *screen = QGuiApplication::primaryScreen(); QRect geometry = screen->geometry(); int screenWidth = geometry.width(); int screenHeight = geometry.height(); QString current= QString("%1x%2").arg(screenWidth).arg(screenHeight); int idx = ui->resolution_comboBox->findText(current); if(idx >= 0){ ui->resolution_comboBox->setCurrentIndex(idx); }else{ ui->resolution_comboBox->insertItem(0,current); ui->resolution_comboBox->setCurrentIndex(0); } QProcess process; process.start("xfreerdp --help"); process.waitForFinished(); QByteArray output = process.readAllStandardOutput(); if (process.exitCode() != 0) { ui->textBrowser->setText("You need to install xfreerdp!"); QMessageBox::warning(this,"NOT FOUND XFREERDP", "You need to install xfreerdp!",QMessageBox::Yes); exit(0); }else{ ui->textBrowser->setText(QString::fromLocal8Bit(output).trimmed()); } } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); ui->port_text->setValidator(new QRegExpValidator(QRegExp("[0-9]{5}"))); GetDefault(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_cancel_button_clicked() { exit(0); } void MainWindow::on_connect_button_clicked() { QString host = ui->host_text->text(); QString port = ui->port_text->text(); QString domain = ui->domain_text->text(); QString username = ui->username_text->text(); QString password = ui->password_text->text(); QString resolution = ui->resolution_comboBox->currentText(); QString bpp = ui->bpp_comboBox->currentText(); QString network= ui->network_comboBox->currentText(); QString audio_mode= ui->audio_comboBox->currentText(); bool full_screen = ui->full_screen_box->isChecked(); bool dynamic_resolution = ui->dynamic_resolution_box->isChecked(); bool compression = ui->compression_box->isChecked(); bool glyph_cache = ui->glyph_cache_box->isChecked(); bool bitmap_cache = ui->bitmap_cache_box->isChecked(); bool async_input = ui->async_input_box->isChecked(); bool async_update = ui->async_update_box->isChecked(); QString shared_directory_name_text = ui->shared_directory_name_text->text(); QString share_directory_text = ui->share_directory_text->text(); QString other_options_text = ui->other_options_text->toPlainText(); QString exec_command = ""; exec_command += QString("/v:'%1':%2").arg(host).arg(port); exec_command += domain!="" ? QString(" /d:'%1'").arg(domain) :"" ; exec_command += QString(" /u:'%1'").arg(username); exec_command += QString(" /p:'%1'").arg(password); exec_command += QString(" /size:%1").arg(resolution); exec_command += QString(" /bpp:%1").arg(bpp); exec_command += QString(" /network:%1").arg(network); exec_command += QString(" /audio-mode:%1").arg(audio_mode); exec_command += full_screen ? " /f" : ""; exec_command += dynamic_resolution ? " /dynamic-resolution" : ""; exec_command += compression ? " /compression" : ""; exec_command += glyph_cache ? " +glyph-cache" : ""; exec_command += bitmap_cache ? " /bitmap-cache" : ""; exec_command += async_input ? " /async-input" : ""; exec_command += async_update ? " /async-update" : ""; exec_command += (!shared_directory_name_text.isEmpty() && !share_directory_text.isEmpty()) ? QString(" /drive:%1,%2").arg(shared_directory_name_text).arg(share_directory_text) : ""; exec_command += QString(" %1").arg(other_options_text); QString program = "xfreerdp"; QString command = QString("%1 %2").arg(program).arg(exec_command); qDebug()<<command; QByteArray byteArray = command.toLocal8Bit(); const char *cmd = byteArray.constData(); int result = system(cmd); } ``` ## main.cpp ```cpp #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } ``` © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏