问题背景
这个问题是我在做海草项目时,要在上位机Jetson Nano上制作相关界面,由于第一次接触该方面,由此写下该篇博客对其进行记录。
一、安装PyQt5
- 使用以下命令安装:
sudo apt install pyqt5* sudo apt-get install python3-pyqt5
- 导入PyQt5包至Python虚拟环境
如果你需要在虚拟环境中使用PyQt5,按如下步骤将系统的PyQt5库链接到你的虚拟环境中- 首先在终端执行以下指令查找编译好的PyQt5库相关文件的路径
sudo find / -iname "PyQt5*" # 得到类似路径/usr/lib/python3/dist-packages/PyQt5 sudo find / -iname "*sip*" # 得到类似路径/usr/lib/python3/dist-packages/sip...
- 随后找到本地虚拟环境的site-packages文件夹,并链接到查找到的PyQt5库相关文件路径即可
ln -s /usr/lib/python3/dist-packages/PyQt5/ /home/nx407/.virtualenv/torchli/lib/python3.6/site-packages # 注意ln,link的意思,不是大写i ln -s /usr/lib/python3/dist-packages/sip* /home/nx407/.virtualenv/torchli/lib/python3.6/site-packages # 注意ln,link的意思,不是大写i
- 安装完成后,在虚拟环境中执行下列指令以确保python能正确调用pyQt5。
import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QMainWindow from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.frame = QtWidgets.QFrame(self.centralwidget) self.frame.setGeometry(QtCore.QRect(60, 50, 120, 80)) self.frame.setStyleSheet("background-color: rgb(0, 170, 0);") self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(250, 60, 101, 91)) self.label.setAlignment(QtCore.Qt.AlignCenter) self.label.setObjectName("label") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.label.setText(_translate("MainWindow", "QLabel")) class MyApp(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) # 设置界面 if __name__ == "__main__": app = QApplication(sys.argv) myapp = MyApp() myapp.show() sys.exit(app.exec_())
- 运行成功后,显示应如下:
- 首先在终端执行以下指令查找编译好的PyQt5库相关文件的路径
二、使用QtDesigner设计界面
2.1 开发流程
- 用PyQt5官方自带的qtdesigner来进行界面设计(简单、高效),使用以下命令打开Jetson上的QtDesigner软件
/usr/lib/aarch64-linux-gnu/qt5/bin/designer # 正常情况下都会默认安装在此位置,如果找不到的话,可以使用上面类似命令搜索designer位置
- 关于QtDesigner的使用,建议上bilibili搜索一下,多看几个相关视频差不多就能应用了。在这里我推荐一个适合小白的Up主:【Python Qt 图形界面编程 - PySide2 PyQt5 PyQt PySide】白月黑羽编程
- 在完成界面的基本布局后,可以通过添加QSS语言来美化你的界面,关于QSS的使用可以参考【QT】史上最全最详细的QSS样式表用法及用例说明
- 最后就可以着手敲代码,来实现自己想要的界面功能了。
2.2 界面设计流程
- 首先确定界面显示平台的分辨率大小
- 然后根据实际需求来构想界面要实现的功能
- 从实现功能角度去设计你的界面布局,如QFrame、Stacked Widget、QPushButton、QLabel等部件的摆放与功能
- 接着对整个界面布局进行美化设计(比如使用Adobe XD软件)
- 最后使用QtDesigner结合QSS实现所设计的界面
需要注意的是,在界面布局设计过程中一定要结合Frame拼接的理念去设计,并且只有第五步才真正需要使用到QtDesigner软件。
三、关于PyQt5开发的经验
3.1 代码开发平台选择
一般而言,我会选择在Windows电脑上先进行PyQt的界面开发,待与界面相关的代码在Windows本地运行没问题后,再将代码移植到Jetson上进行运行检查。但这样做的前提是,一定要将Windows平台上的PyQt5与Jetson上安装的保持版本一致(或者能兼容运行)即可。
3.2 QtDesigner开发的理解
使用QtDesigner设计得到的界面是一个个Frame或者Widget组合嵌套而成,而使用者可以在Frame或Widget中添加Label和PushButton等元素来实现一些交互功能。在完成界面的基本布局后,可以通过QSS语言来美化你的界面,界面的一些交互功能大部分都需要使用你的代码实现。
四、Jetson Nano桌面的布局设计
由于Jetson nano的桌面布局,通常会导致我们的界面无法完全铺满整个屏幕(如下图所示),进而就会导致我们设计的界面在布局、美观等方面受到影响,因此需要对Jetson nano的桌面布局进行修改。
4.1 隐藏桌面的侧栏
- 首先安装gnome tweak:
sudo apt install gnome-tweaks
- 确保当前账号登录的桌面是gnome tweak
- 退出当前系统,log out
- 然后点击gnome,再登录,否则接下来无法找到下面操作要使用到的Extensions一项。如下图所示:
- 安装扩展dash to dock
sudo apt-get install gnome-shell-extension-dashtodock
- 重新启动系统,命令行输入
reboot
- 重启后,命令行输入
gnome-tweaks
打开工具,然后按如下进行桌面配置——取消侧栏- 点击红框Extension选项
- 点击红框选项,打开Dash to dock,并点击绿框进行配置桌面。如下图所示:
- 之后按下图所示进行设置
- 点击红框Extension选项
4.2 隐藏桌面的顶栏
- 安装拓展hide top bar
sudo apt-get install gnome-shell-extension-autohidetopbar
- 安装成功后,命令行输入
gnome-tweaks
打开工具,步骤同上 - 然后进行桌面配置——取消顶栏,即打开Hide to bar
4.3 界面效果展示
当进行完上述修改后,可以发现界面可以铺满整个屏幕了。