我正在使用以下“必需”版本:
- Python 3.6.4
- PyQt5 5.9.2
运行“fbs”
我完全没有问题让我的应用程序通过“fbs run”运行……应用程序运行完美
我完成了“fbs freeze”……没问题,但是在运行“fbs 安装程序”并执行 .dmg 文件(我在 macOS - Catalina - 10.15.2 上)并将其拖到我的应用程序文件夹中之后一切似乎都可以工作,但是当我尝试启动现在安装的应用程序时……它开始启动图标和扩展坞,然后就关闭了。
当我注释掉与数据库相关的代码时。这一切都完美无缺。那就是我能够完全启动我的应用程序
我配置我的应用程序的第一种方式。
在 main.py 中:
appctxt.get_resource("../resources/plants.db”)
我把我的数据库文件放在:“src/main/resources”
当我这样操作时,我得到了上面描述的行为(应用程序尝试启动并立即关闭)
我配置应用程序的第二种方式。 我开始四处寻找是否可以解决问题。所以我在目标目录中找到了一个“资源”目录我尝试通过以下可执行文件启动我的应用程序:target/testPlants.app/Contents/ 当我这样做时,mac CMD 窗口出现,我看到它告诉我,它无法在我在“get_resource”方法中指定的路径找到我的数据库。
所以我发现目标目录中的资源目录是大写的,像这样:
target/testPlants.app/Contents/Resources,我看到我的数据库按预期存储在“资源”目录中。所以我将 main.py 中的 appctxt.get_resource 语句更改为:
appctxt.get_resource("../Resources/plants.db”)
事实上,当我尝试通过以下目录中的 .exe 启动它并且我的应用程序启动时,我不再收到错误消息......(我没有得到我的图标,但它启动了! )
所以我在想,我在某个地方。
所以我继续尝试通过在运行具有此路径更改的安装程序后双击应用程序图标来启动我的应用程序(使用大写的“资源”),我现在收到一个新错误
Could not open database file: out of memory
(见下文)屏幕截图 2020-04-19 在 2.46.11 PM.png
Reproducible Sample 使用代码原样...当我检查目标目录中的资源目录时,该目录是由于 fbs 冻结而创建的,其中没有 db,因此应用程序尝试启动(在我运行安装程序),然后关闭。如果我手动将数据库放入其中,它会给我“内存不足”错误。谢谢参观
from fbs_runtime.application_context.PyQt5 import ApplicationContext
from fbs_runtime.application_context import cached_property
import sys, csv
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
from PyQt5 import QtSql as qts
from PyQt5.QtPrintSupport import QPrintDialog, QPrinter, QPrintPreviewDialog
from PyQt5.Qt import QFileInfo
import sqlite3
from datetime import date
from PyQt5.QtGui import QPixmap
class MainWindow(qtw.QMainWindow):
def __init__(self):
super().__init__()
self.gridLayout = qtw.QGridLayout()
self.mainW = qtw.QWidget()
self.mainW.setLayout(self.gridLayout)
self.setCentralWidget(self.mainW)
# Connect to the database
db = qts.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('plants.db')
if not db.open():
qtw.QMessageBox.critical(
None, 'DB Connection Error',
'Could not open database file: '
f'{db.lastError().text()}')
sys.exit(1)
#CREATE MODELS FOR EACH SQL TABLE
self.zone_model = qts.QSqlTableModel()
self.zone_model.setTable('zones')
self.loc_model = qts.QSqlTableModel()
self.loc_model.setTable('loc_rec')
self.indoor_seed_model = qts.QSqlTableModel()
self.indoor_seed_model.setTable('indoor_seed')
self.soil_rec_model = qts.QSqlTableModel()
self.soil_rec_model.setTable('soil_rec')
self.plant_type_model = qts.QSqlTableModel()
self.plant_type_model.setTable('plant_type')
self.nick_name_model = qts.QSqlTableModel()
self.plant_type_model.setTable('nick_name')
self.plants_model = qts.QSqlRelationalTableModel()
self.plants_model.setTable('plant_list')
self.plants_model.setRelation(
self.plants_model.fieldIndex('nickname_id'),
qts.QSqlRelation('nick_name', 'id', 'veggies')
)
self.plants_model.setRelation(
self.plants_model.fieldIndex('ans_id'),
qts.QSqlRelation('indoor_seed', 'id', 'ans')
)
self.plants_model.setRelation(
self.plants_model.fieldIndex('zone_id'),
qts.QSqlRelation('zones', 'id', 'code')
)
self.plants_model.setRelation(
self.plants_model.fieldIndex('soil_id'),
qts.QSqlRelation('soil_rec', 'id', 'soil_type')
)
self.plants_model.setRelation(
self.plants_model.fieldIndex('p_type_id'),
qts.QSqlRelation('plant_type', 'id', 'p_type')
)
self.plants_model.setRelation(
self.plants_model.fieldIndex('location_id'),
qts.QSqlRelation('loc_rec', 'id', 'loc')
)
self.UIComps() # call the UI components method
def UIComps(self):
# set headers for main table
fieldnames = ['ID', "Year Planted", "Real Name", "Nick Name", "Description",
"Seed Plant Rec","Garden Plant Rec", "Plant Notes", "Comments",
"Days to Germ", "Days to Harv","Reco Spring Frost","Actual Spring Frost", "Seed Plant Rec", "Garden Plant Rec",
"Actual Seed Plant", "Actual Garden Plant", "Harvest Date Plan", "Actual Harvest Date",
"Photo", "Location", "Zone", "Seed Indoor?", "Soil Type", "Plant Type" ]
c = 0
for f in fieldnames:
self.plants_model.setHeaderData(c, qtc.Qt.Horizontal, (fieldnames[c]))
c += 1
self.plants_model.setEditStrategy(qts.QSqlTableModel.OnFieldChange)
# self.plants_model.dataChanged.connect(print)
lbl2 = qtw.QLabel("View/Edit Plants", self)
lbl2.setFont(qtg.QFont("Helvetica", 25, 12))
self.gridLayout.layout().addWidget(lbl2, 6, 0,1,3, alignment=qtc.Qt.AlignCenter)
#PLANT LIST TABLE
self.plant_list = qtw.QTableView()
self.plant_list.setSelectionMode(qtw.QAbstractItemView.ExtendedSelection)
self.plant_list.setDragEnabled(True)
self.plant_list.setAcceptDrops(True)
self.plant_list.setDropIndicatorShown(True)
self.plant_list.setDragDropMode(qtw.QAbstractItemView.InternalMove)
self.plant_list.setModel(self.plants_model)
self.gridLayout.layout().addWidget(self.plant_list, 7, 0, 2, 3)
self.plant_list.horizontalHeader().setSectionsClickable(True)
self.plant_list.horizontalHeader().setSortIndicatorShown(True)
self.plant_list.setSortingEnabled(True) # this makes table sortable
self.plants_model.setEditStrategy(qts.QSqlTableModel.OnFieldChange)
self.plants_model.dataChanged.connect(print)
self.plants_model.select()
self.plant_list.setItemDelegate(qts.QSqlRelationalDelegate())
#adding toolbars
self.toolbar = self.addToolBar('Controls')
deleteCoffee = qtw.QAction(qtg.QIcon("close.png"), "Delete Record", self)
deleteCoffee.triggered.connect(self.delete_plant) #removes from table
self.toolbar.addAction(deleteCoffee )
addPlant = qtw.QAction(qtg.QIcon("add.png"), "Add A Plant", self)
addPlant.triggered.connect(self.add_plant)
self.toolbar.addAction(addPlant)
# SLOTS for Toolbar buttons
def delete_plant(self):
selected = self.plant_list.selectedIndexes()
for index in selected or []:
self.plants_model.removeRow(index.row())
self.plants_model.select()
def add_plant(self):
self.gridLayout.layout().addWidget(self.plant_list, 7, 0, 2, 3)
self.plants_model.insertRows(0, 1)
appctxt = ApplicationContext()
appctxt.get_resource("../resources/plants.db")
appctxt.get_resource("../resources/add.png")
mw = MainWindow()
mw.setGeometry(10, 10, 900, 650)
mw.show()
exit_code = appctxt.app.exec_()
sys.exit(exit_code)
更新- 我相信我修复了数据库问题,对代码和配置进行了以下更改,但在运行“fbs freeze”后我仍然无法看到我的图像
以下是我对数据库所做的更改:
- 对我来说,第一个数据库必须位于“资源”的子目录中,而不是直接使用资源,所以对我来说是这样的:
src/main/资源/基础
- 接下来,我假设我的“main.py”中的路径会模仿上面的路径(换句话说,我放置数据库的位置(src/main/resources/base))。相反,这似乎对我有用:
appctxt.get_resource("plants.db")
我现在没有关于无法找到数据库的错误,但是,当我运行可执行文件时,我的图像/图标都没有显示,这对我来说,启用了应用程序和数据库的导航。
在阅读文档时,图像似乎遵循与数据文件/数据库相同的逻辑,但这似乎对我不起作用。它在我执行“fbs run”时起作用,但在我启动应用程序的可执行文件时在“fbs freeze”之后不起作用。应用程序启动时没有错误,但没有图像。
我的图像配置与数据库相同:
- 我已将它们加载到名为“base”的“资源”的子目录中,如下所示
src/main/资源/基础
- 至于“main.py”文件中的语句,我有以下内容:
appctxt.get_resource("carrots.jpg")
appctxt.get_resource("csv.png")
appctxt.get_resource("csv2.png")
appctxt.get_resource("leeks.jpg")
appctxt.get_resource("list.png")
appctxt.get_resource("close.png")
appctxt.get_resource("mushrooms.jpg")
appctxt.get_resource("pdf.png")
appctxt.get_resource("potato.jpg")
appctxt.get_resource("Rosce.png")
appctxt.get_resource("seed.png")
appctxt.get_resource("tomato.jpg")
appctxt.get_resource("veggies.png")
appctxt.get_resource("year.png")
有人对图像有好运吗?有不同的方法来配置它们吗?谢谢
进一步更新
当我继续尝试解决这个问题时,在“fbs freeze”之后,我可以确认 fbs 将数据库和图像传输到:“target//Contents/Resources”目录,但我认为它并没有真正看到任何一位。
此外,我是否包括以下内容似乎没有什么区别:
# appctxt.get_resource("add.png")
# appctxt.get_resource("carrots.jpg")
在 main.py
我想我不完全理解在什么条件下我需要包含 .get_resource() 方法以及如何配置它。我在这里看到了这个例子,但不知道如何让它与我的数据库一起使用,或者我什至需要。从逻辑上讲,我这样做了。我会继续挖掘,但如果有人有见识,我会很感激任何提示。
更新 - 已修复!
我终于想通了,我希望这对其他人有帮助。
- 这部分我做对了,数据文件、图像和数据库在这里:
src/main/资源/基础
- 以下是我如何获取数据库代码以使其被识别:
db = qts.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName(appctxt.get_resource("plants.db"))
if not db.open():
qtw.QMessageBox.critical(
None, 'DB Connection Error',
'Could not open database file: '
f'{db.lastError().text()}')
sys.exit(1)
我需要将 get_resource() 方法放在 PyQt 的 QSqlDatabase 类的 setDatabaseName() 方法中。
对于图像我需要做这样的事情:
ros = appctxt.get_resource("Rosce.png")
pixmap = qtg.QPixmap(ros)
或者,如果使用 setStyle 方法,如下所示:
seed = appctxt.get_resource("seed.png")
self.btnSeed.setStyleSheet("image: url(" + seed + ");")