3、从原型到代码:Figma设计稿导出、使用Qt Designer还原界面、理解UI文件结构
说实话,很多做桌面应用的朋友,都卡在「设计稿变代码」这一步。
设计稿画得漂漂亮亮,一到写代码就手忙脚乱。要么布局对不上,要么间距差一像素。我早期做项目时也踩过这个坑,后来摸索出一套流程——从Figma导出,到Qt Designer还原,再到理解UI文件结构。今天就把这套方法掰开揉碎讲给你听。
3.1 从Figma导出设计稿:别小看这一步
很多人觉得导出就是点个按钮。其实不然。我见过太多人导出一堆乱七八糟的素材,最后还得自己重新拼。
正确的导出姿势是这样的:
- 先整理图层——把同类型的控件放到一个组里。比如所有按钮放一组,所有输入框放一组。我在项目中习惯用「Btn_」「Input_」这样的前缀命名,方便后续查找。
- 导出为SVG——Qt Designer对SVG支持很好,而且SVG是矢量图,缩放不失真。我曾经试过用PNG,结果在高DPI屏幕上糊得一塌糊涂。
- 注意导出尺寸——Figma里设计稿通常是1x,但Qt Designer里可能需要2x。我的做法是:导出时直接选2x,省得后面再调。
小技巧: 如果你设计稿里有图标,建议单独导出。别把图标和背景混在一起,否则在Qt里很难做状态切换(比如hover效果)。
3.2 使用Qt Designer还原界面:从「看」到「做」
打开Qt Designer,第一件事不是拖控件,而是设置布局策略。我见过太多新手一上来就拖控件,结果窗口一拉伸,界面全乱套。
我的还原步骤:
- 先搭骨架——用QWidget或QFrame把界面分区。比如左侧导航区、右侧内容区、底部状态栏。这一步对应Figma里的「大区块」。
- 再填细节——往每个区里放具体控件。按钮、标签、输入框……注意对齐。Qt Designer有对齐辅助线,用起来很方便。
- 最后调样式——用QSS(Qt样式表)设置颜色、字体、圆角。这部分我后面会专门讲。
重点: 布局一定要用「布局管理器」(QHBoxLayout、QVBoxLayout、QGridLayout)。别用绝对布局,否则在不同分辨率下会出问题。我早期一个项目就是因为用了绝对布局,结果用户换了个4K屏,界面直接崩了。
3.3 理解UI文件结构:它其实是个XML
Qt Designer保存的文件是.ui格式。你如果用记事本打开它,会发现它就是个XML文件。嗯,说白了就是一堆标签。
一个典型的UI文件结构:
<?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>800</width>
<height>600</height>
</rect>
</property>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>点击我</string>
</property>
</widget>
</widget>
</ui>
你看,结构其实很清晰:
<ui>——根节点,版本号<class>——这个界面对应的Python类名<widget>——每个控件,class属性是控件类型,name是对象名<property>——控件的属性,比如位置、大小、文本
注意: 千万别手动修改UI文件!我试过,改完Qt Designer就打不开了。要改就在Qt Designer里改,或者用代码动态修改。
3.4 从UI文件到Python代码:两种方式
UI文件不能直接运行,得转成Python代码。有两种方式:
| 方式 | 命令/方法 | 适用场景 |
|---|---|---|
| 静态转换 | pyuic5 -o output.py input.ui |
界面固定不变时 |
| 动态加载 | uic.loadUi('input.ui', self) |
界面需要频繁修改时 |
我个人推荐动态加载。 为什么呢?因为开发过程中界面改来改去是常事。如果用静态转换,每次改完UI文件都得重新运行命令,很烦。动态加载的话,改完UI文件直接运行程序就行。
举个例子:
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi('mainwindow.ui', self) # 动态加载UI文件
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
你看,代码就这么几行。UI文件里放什么控件,程序里就能直接用。比如UI里有个按钮叫pushButton,代码里直接self.pushButton就能访问。
避坑指南: 我曾经犯过一个错——UI文件里控件名用了中文。结果动态加载时报错,说找不到对象。后来我学乖了,所有控件名都用英文,最多加个下划线。比如
btn_login、input_password。
3.5 实战:还原一个登录界面
光说不练假把式。咱们拿一个登录界面来实操。
Figma设计稿长这样:
- 顶部:Logo(一张图片)
- 中间:用户名输入框、密码输入框、登录按钮
- 底部:注册链接
在Qt Designer里还原:
- 拖一个QWidget作为主容器,设置垂直布局
- 放一个QLabel放Logo,设置
pixmap属性 - 放两个QLineEdit,一个设
placeholderText为「请输入用户名」,另一个设echoMode为Password - 放一个QPushButton,文本设为「登录」
- 放一个QLabel,文本设为「没有账号?注册」
对应的UI文件结构:
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_logo">
<property name="pixmap">logo.png</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_username"/>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_password"/>
</item>
<item>
<widget class="QPushButton" name="pushButton_login"/>
</item>
<item>
<widget class="QLabel" name="label_register"/>
</item>
</layout>
</widget>
你看,结构一目了然。每个控件都在对应的布局里,顺序就是从上到下。
核心思路: 从Figma到Qt Designer,不是「照着画」,而是「理解结构」。设计稿里的每个区块,对应Qt里的一个容器;每个控件,对应Qt里的一个widget。理解了这一点,还原界面就是水到渠成的事。
好了,这一章就到这里。下一章咱们聊聊「信号与槽」——说白了就是怎么让按钮点下去有反应。到时候见。