首先安装python3.6 安装教略 新建个文件夹(testfbs) 进入 testfbs目录下 在testfbs下打开控制台 创建python虚拟环境命令如下:

python -m venv venv
进入环境目录 命令如下:

cd venv/scripts/

在此环境激活环境命令如下:

activate.bat

activate python36

venv/scripts/在目录下执行安装fbs

pip install fbs -i https://pypi.doubanio.com/simple

接着new一个新窗口在testfbs目录下

执行下面命令创建项目(为什么这样因为你要使用虚拟环境中的fbs)

D:\testfbs\venv\Scripts\fbs startproject

执行命令之后就会出现输入项目名字之类的 填写后项目就算创建成功了

接着就是打开D:\testfbs\src\main\python目录

这个下会有一个main.py

下面是一个我打包2048的一个例子代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox
from PyQt5.QtGui import QPainter, QColor, QFont, QPen
from PyQt5.QtCore import Qt, QRect
import sys
import os
import copy
import random
class GameForm(QMainWindow):def __init__(self, parent=None):super(GameForm, self).__init__(parent)self.initUi()# 定义各数字的背景颜色self.colors = {0: (204, 192, 179), 2: (238, 228, 218), 4: (237, 224, 200),8: (242, 177, 121), 16: (245, 149, 99), 32: (246, 124, 95),64: (246, 94, 59), 128: (237, 207, 114), 256: (237, 207, 114),512: (237, 207, 114), 1024: (237, 207, 114), 2048: (237, 207, 114),4096: (237, 207, 114), 8192: (237, 207, 114), 16384: (237, 207, 114),32768: (237, 207, 114), 65536: (237, 207, 114), 131072: (237, 207, 114),262144: (237, 207, 114), 524288: (237, 207, 114), 1048576: (237, 207, 114)}self.initGameData()self.chiese_grid = ["","相遇", "初识", "爱慕", "暧昧", "试探", "表白", "尴尬", "牵手", "热恋", "分手", "", "", "", "", "", "", "", ]self.chiese_grid1 = ["","北齐", "北周", "北魏", "隋朝", "唐朝", "宋朝", "明朝", "清朝", "民国", "中国", "", "", "", "", "", "", "", ]self.chiese_grid2 = ["","相遇", "初识", "爱慕", "暧昧", "试探", "表白", "尴尬", "牵手", "热恋", "分手", "", "", "", "", "", "", "", ]def is2powern(self, s):if s==0:return 0elif s==1:return 1for i in range(1,100):if 2**i==s:return idef initUi(self):self.setWindowTitle("2048")self.resize(505, 720)self.setFixedSize(self.width(), self.height())self.initGameOpt()def initGameOpt(self):''' 初始化游戏配置 '''self.lbFont = QFont('SimSun', 12)  # label字体self.lgFont = QFont('SimSun', 50)  # Logo字体self.nmFont = QFont('SimSun', 36)  # 面板数字字体def initGameData(self):''' 初始化游戏数字 '''self.data = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]count = 0while count < 2:row = random.randint(0, len(self.data) - 1)col = random.randint(0, len(self.data[0]) - 1)if self.data[row][col] != 0:continueself.data[row][col] = 2 if random.randint(0, 1) else 4count += 1self.curScore = 0self.bstScore = 0# 载入最高得分if os.path.exists("bestscore.ini"):with open("bestscore.ini", "r") as f:self.bstScore = int(f.read())def paintEvent(self, e):''' 重写绘图事件 '''qp = QPainter()qp.begin(self)self.drawGameGraph(qp)qp.end()def keyPressEvent(self, e):keyCode = e.key()ret = Falseif keyCode == Qt.Key_Left:ret = self.move("Left")elif keyCode == Qt.Key_Right:ret = self.move("Right")elif keyCode == Qt.Key_Up:ret = self.move("Up")elif keyCode == Qt.Key_Down:ret = self.move("Down")else:passif ret:self.repaint()def closeEvent(self, e):# 保存最高得分with open("bestscore.ini", "w") as f:f.write(str(self.bstScore))def drawGameGraph(self, qp):''' 绘制游戏图形 '''self.drawLog(qp)self.drawLabel(qp)self.drawScore(qp)self.drawBg(qp)self.drawTiles(qp)def drawScore(self, qp):''' 绘制得分 '''qp.setFont(self.lbFont)fontsize = self.lbFont.pointSize()scoreLabelSize = len(u"SCORE") * fontsizebestLabelSize = len(u"BEST") * fontsizecurScoreBoardMinW = 15 * 2 + scoreLabelSize  # SCORE栏的最小宽度bstScoreBoardMinW = 15 * 2 + bestLabelSize  # BEST栏的最小宽度curScoreSize = len(str(self.curScore)) * fontsizebstScoreSize = len(str(self.bstScore)) * fontsizecurScoreBoardNedW = 10 + curScoreSizebstScoreBoardNedW = 10 + bstScoreSizecurScoreBoardW = max(curScoreBoardMinW, curScoreBoardNedW)bstScoreBoardW = max(bstScoreBoardMinW, bstScoreBoardNedW)qp.setBrush(QColor(187, 173, 160))qp.setPen(QColor(187, 173, 160))qp.drawRect(505 - 15 - bstScoreBoardW, 40, bstScoreBoardW, 50)qp.drawRect(505 - 15 - bstScoreBoardW - 5 - curScoreBoardW, 40, curScoreBoardW, 50)bstLabelRect = QRect(505 - 15 - bstScoreBoardW, 40, bstScoreBoardW, 25)bstScoreRect = QRect(505 - 15 - bstScoreBoardW, 65, bstScoreBoardW, 25)scoerLabelRect = QRect(505 - 15 - bstScoreBoardW - 5 - curScoreBoardW, 40, curScoreBoardW, 25)curScoreRect = QRect(505 - 15 - bstScoreBoardW - 5 - curScoreBoardW, 65, curScoreBoardW, 25)qp.setPen(QColor(238, 228, 218))qp.drawText(bstLabelRect, Qt.AlignCenter, u"BEST")qp.drawText(scoerLabelRect, Qt.AlignCenter, u"SCORE")qp.setPen(QColor(255, 255, 255))qp.drawText(bstScoreRect, Qt.AlignCenter, str(self.bstScore))qp.drawText(curScoreRect, Qt.AlignCenter, str(self.curScore))def drawBg(self, qp):''' 绘制背景图 '''col = QColor(187, 173, 160)qp.setPen(col)qp.setBrush(QColor(187, 173, 160))qp.drawRect(15, 150, 475, 475)  # 绘制游戏区域def drawLog(self, qp):''' 绘制Logo '''pen = QPen(QColor(255, 93, 29), 15)qp.setFont(self.lgFont)qp.setPen(pen)qp.drawText(QRect(10, 0, 150, 130), Qt.AlignCenter, "2048")def drawLabel(self, qp):''' 绘制所有标签信息 '''qp.setFont(self.lbFont)qp.setPen(QColor(119, 110, 101))qp.drawText(15, 134, u"合并相同数字,得到2048吧!")qp.drawText(15, 660, u"怎么玩:")qp.drawText(45, 680, u"用-> <- 上下左右箭头按键来移动方块.")qp.drawText(45, 700, u"当两个相同数字的方块碰到一起时,会合成一个!")def drawTiles(self, qp):''' 绘制数字背景 '''qp.setFont(self.nmFont)for row in range(4):for col in range(4):value = self.data[row][col]color = self.colors[value]qp.setPen(QColor(*color))qp.setBrush(QColor(*color))qp.drawRect(30 + col * 115, 165 + row * 115, 100, 100)  # 绘制数字的背景小方块size = self.nmFont.pointSize() * len(str(value))  # 获取当前字体下显示数字的长度# 根据尺寸调整字体大小while size > 100 - 15 * 2:self.nmFont = QFont('SimSun', self.nmFont.pointSize() * 4 // 5)qp.setFont(self.nmFont)size = self.nmFont.pointSize() * len(str(value))  # 获取当前字体下显示数字的长度print("[%d][%d]: value[%d] weight: %d" % (row, col, value, size))# 显示非0数字if value == 2 or value == 4:qp.setPen(QColor(119, 110, 101))  # 设置2和4数字的前景色else:qp.setPen(QColor(255, 255, 255))  # 设置其他数字的前景色if value != 0:rect = QRect(30 + col * 115, 165 + row * 115, 100, 100)# 这里可以将其改为中文# qp.drawText(rect, Qt.AlignCenter, str(value))print(value)qp.drawText(rect, Qt.AlignCenter, self.chiese_grid1[self.is2powern(value)])def putTile(self):''' 找到一个空位置(数值为0),并随机填充2或4 '''available = []for row in range(len(self.data)):for col in range(len(self.data[0])):if self.data[row][col] == 0:available.append((row, col))if available:row, col = available[random.randint(0, len(available) - 1)]self.data[row][col] = 2 if random.randint(0, 1) else 4return Truereturn Falsedef merge(self, row):''' 合并一行或一列 '''pair = FalsenewRow = []for i in range(len(row)):if pair:newRow.append(2 * row[i])self.curScore += 2 * row[i]pair = Falseelse:# 可以和if i + 1 < len(row) and row[i] == row[i + 1]:pair = Trueelse:# 不可以和newRow.append(row[i])return newRowdef slideUpDown(self, isUp):''' 上下方向移动数字方格 '''numRows = len(self.data)numCols = len(self.data[0])oldData = copy.deepcopy(self.data)for col in range(numCols):cvl = []for row in range(numRows):if self.data[row][col] != 0:cvl.append(self.data[row][col])  # 将列里面的非0元素提取出来if len(cvl) >= 2:# 看看能不能合并cvl = self.merge(cvl)  # 合并相同数字# 根据移动方向填充0for i in range(numRows - len(cvl)):if isUp:cvl.append(0)else:cvl.insert(0, 0)print("row=%d" % row)row = 0for row in range(numRows):self.data[row][col] = cvl[row]return oldData != self.data  # 返回数据是否发生了变化def slideLeftRight(self, isLeft):''' 左右方向移动数字方格 '''numRows = len(self.data)numCols = len(self.data[0])oldData = copy.deepcopy(self.data)for row in range(numRows):rvl = []for col in range(numCols):if self.data[row][col] != 0:rvl.append(self.data[row][col])if len(rvl) >= 2:rvl = self.merge(rvl)for i in range(numCols - len(rvl)):if isLeft:rvl.append(0)else:rvl.insert(0, 0)col = 0for col in range(numCols):self.data[row][col] = rvl[col]return oldData != self.datadef move(self, direction):''' 移动数字方格 '''isMove = Falseif direction == "Up":isMove = self.slideUpDown(True)elif direction == "Down":isMove = self.slideUpDown(False)elif direction == "Left":isMove = self.slideLeftRight(True)elif direction == "Right":isMove = self.slideLeftRight(False)else:passif not isMove:return Falseself.putTile()  # 新增一个数字if self.curScore > self.bstScore:self.bstScore = self.curScoreif self.isGameOver():button = QMessageBox.warning(self, "Warning", u"游戏结束,是否重新开始?",QMessageBox.Ok | QMessageBox.No,QMessageBox.Ok)if button == QMessageBox.Ok:self.initGameOpt()bstScore = self.bstScoreself.initGameData()self.bstScore = bstScorereturn Trueelse:return Falseelse:return Truedef isGameOver(self):''' 判断游戏是否无法继续 '''copyData = copy.deepcopy(self.data)  # 先暂存数据值curScore = self.curScoreflag = Falseif not self.slideUpDown(True) and not self.slideUpDown(False) and \not self.slideLeftRight(True) and not self.slideLeftRight(False):flag = True  # 全部方向都不能再移动self.curScore = curScoreif not flag:self.data = copyData  # 仍可以移动,则恢复原来数据return flagif __name__ == '__main__':appctxt = ApplicationContext()  # 1. Instantiate ApplicationContextapp = QApplication(sys.argv)form = GameForm()form.show()exit_code = appctxt.app.exec_()  # 2. Invoke appctxt.app.exec_()sys.exit(exit_code)

其实main.py中的代码是一个最小的打包例子重点就是这几句

from fbs_runtime.application_context.PyQt5 import ApplicationContext
if __name__ == '__main__':appctxt = ApplicationContext()  # 1. Instantiate ApplicationContextapp = QApplication(sys.argv)# 下这两句是调用你自己的程序其他不变form = GameForm()form.show()# 上这两句是调用你自己的程序其他不变exit_code = appctxt.app.exec_()  # 2. Invoke appctxt.app.exec_()sys.exit(exit_code)

当前目录下还有一个图标,你可以直接将自己的图标命名为这个官方给的图标是一样的这样就可以了

还有就会说资源路径问题(比如你写的是src/test.jpg)那么就这样写

import os
basepath=os.path.split(os.path.abspath(__file__))[0]
path=os.path.join(basepath,"src/test.jpg")

接着就执行 执行一定会报错 哪里错改哪里最常现的就是缺少包

D:\testfbs\venv\Scripts\fbs run

那么就使用如下操作安装你的包 继续run 直到跑起来

D:\testfbs\venv\Scripts\pip install PyQt5-sip -i https://pypi.doubanio.com/simple
D:\testfbs\venv\Scripts\pip install PyQt5 -i https://pypi.doubanio.com/simple

代码跑成功后
直接执行下面命令
D:\testfbs\venv\Scripts\fbs freeze

执行后你会在testfbs目录下看到target文件夹 在这个文件夹中会两个文件夹一个是PyInstaller和另一个也就是你之前填写的项目名字假如你起名wei wei目录下就会有一个可执行文件好那么在打开执行文件之前 你要将资源(src)整个文件夹直接粘到此目录下 如果不出意外你的软件就打包成功了 你可以直接将target这个文件分享给任何人当然要是同一平台的

使用fbs打包pyqt5本人亲自尝试过的相关推荐

  1. Qt for Python Mac下使用 fbs 打包软件

    Python打包工具 Python的常用的打包工具包括:fbs.PyInstaller.cx_Freeze.py2exe.py2app,而Qt for Python是一个跨平台的框架,因此我们希望专注 ...

  2. 腾讯云centos7搭建javaweb服务器(本人亲自经历,详细)

    首先声明,这是本人亲自搭建成功的经历,亲测有效,****(此处和谐)网上好多在云服务器上搭建javaweb的教程,好多都是各种抄的或者若干年之前的,真的是被坑惨了!废话不多说,下面直接上干货!步骤很详 ...

  3. MAC 安装brew raw.githubusercontent.com port 443: Connection refused 本人亲自认证过,踩过多种方案,最终认证的解决方案

    MAC 安装brew raw.githubusercontent.com port 443: Connection refused 本人亲自认证过,踩过多种方案,最终认证的解决方案 原因:由于某些你懂 ...

  4. pyinstaller 打包pyqt5程序出现环境变量错误问题

    打包pyqt5成exe后发现自定义的环境变量不能正常使用 然后发现 了 import os BASE_DIR = os.path.dirname(os.path.abspath(__file__)) ...

  5. python2打包pyQT5

    pip install python-qt5==0.1.10 pip install PyInstaller==3.6 系统版本window10 创建win-test.py程序 import sys ...

  6. 和平精英吃鸡神器摇杆怎么控制?可以diy你尝试过吗?

    和平精英吃鸡神器摇杆怎么控制?可以diy你尝试过吗? #吃鸡神器 #手柄 #春节不打烊 自动压,不用调试,5个功能,可以玩摇杆走位的游戏通用 可以 DIY 的摇杆,你尝试过吗? 一个手柄 4 大功能, ...

  7. 昂达VX530刷机(本人亲自试过)

    先到官网上下载升级软件点击网址,界面如下: 把两个全下载下来,解压后照说明一步一步来行了. 注意:1.一定要把开关键按到off上. 2.有些在电脑上无法识别的照里面的说明就可以识别了,一定要细细看说明 ...

  8. [python学习笔记] pyinstaller打包pyqt5程序无法运行

    问题 pyinstaller打包的pyqt5程序在部分电脑上会失败.用户截图提示下边错误日志 无法定位程序输入点 ucrtbase.terminate 于动态链接库 api-ms-win-crt-ru ...

  9. 罗永浩直播带货被吐槽不是全网最低价 本人亲自回应了

    罗永浩直播首秀中,遭到很多网友吐槽直播带货中价格不是"全网最低价",对此,他本人在社交媒体推特上亲自回应了. 罗永浩表示,绝大多数都是几大电商平台在事后为了蹭流量故意做低价格,甚至 ...

最新文章

  1. python dict下标_Python基础教程:python的数据类型
  2. VMware中linux与window目录共享
  3. mysql笔记一——安装和设置root密码
  4. 关于我之前写的修改Windows系统Dos下显示的用户名之再修改测试
  5. 摘自《读者》的哲理短句——赞美篇
  6. Java迭代器ListIterator
  7. v-show 与 v-if区别
  8. Notepad++ 配置java编译环境
  9. PHP获取当前文件路径,上层目录路径
  10. php案例之后台数据显示-- mysqli面向对象版(Object Oriented Programming = OOP)
  11. Atitit lucence es solr的各种query 与sql运算符的对比 目录 1.1. 等于运算 TermQuery 1 1.2. 范围运算 1 1.3. 大小运算 1 1.4. Wi
  12. 杜立特尔分解法 MATLAB,chase追赶法算法
  13. hmssdk php,接入华为推送,开发流程, 与遇到的坑(PUSH SDK 和 HMS SDK)
  14. 【2020模拟赛day6】B. 选择人员
  15. 另类搞笑:自我指涉例句不完全收集
  16. 用友java开发待遇_【北京用友软件工资】java开发工程师待遇-看准网
  17. JavaWeb笔记01(mysql)
  18. 表单中enter键,导致表单提交
  19. Cookie跨域setDomain
  20. 投影坐标系的shp数据,如何获取到它地理坐标系下的经纬度坐标

热门文章

  1. 已解决Cause: java.sql.SQLException: Incorrect string value: ‘\\xF0\\x9F\\x8C\\xB8 \\xE5...‘报错
  2. 360浏览器卸载_如何卸载360浏览器,如何卸载360安全浏览器
  3. php的优势和背景,CSS_CSS 多图片融合背景定位的应用于优缺点分析,1. 关键字, 例如: background-positio - phpStudy...
  4. matlab变量区表示函数,MATLAB中的工作区,变量和函数
  5. r语言如何写入一个excel_R语言如何进行聚类分析?
  6. oracle12c spa,Oracle12c功能加强 新特性之管理功能的加强
  7. 荣耀手表magic2更新鸿蒙时间表,荣耀手表2更新百种运动模式 618期间到手价799元起...
  8. linux更新驱动脚本,编写Linux驱动常见错误(不断更新)!
  9. 个人高效写作MarkDown博文模板
  10. 【 Vivado 】Working with Sources in Non-Project Mode