简体   繁体   中英

QSettings doesn't work after building onefile using pyinstaller

I am having an issue when building pyinstaller onefile version of my script my checkbox state doesn't get saved, but in the other hand when pyinstaller building normal exe with files the checkbox state is saved and works perfectly.

Note that I am using resources(package)> __init__.py to store my icons and config.ini and the icons works in both cases onefile or normal build.

Project files picture

__init__.py contents

from pathlib import Path

resources = Path(__file__).parent

config_ini = resources / "config.ini"

My PyQt5 Gui.

import sys

from PyQt5.QtCore import QSettings

import resources

import PyQt5.QtCore
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *



settings = QSettings(str(resources.config_ini), QSettings.IniFormat)


class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.main_ui()
        self.buttons()
        self.layout()
        self.show()
        settings.sync()


    def main_ui(self):
        self.setWindowTitle("Files Organizer")

    def buttons(self):
        self.checkbox_startup = QCheckBox("Run on start up")

        self.checkbox_startup.setChecked(False)
        self.checkbox_startup.setChecked(settings.value("startup_state", type=bool))

        self.checkbox_startup.toggled.connect(self.startup_settings)

    def layout(self):
        self.horizontalGroupBox_options = QGroupBox("Options", self)
        verticalbox_options = QVBoxLayout()
        verticalbox_options.addWidget(self.checkbox_startup)
        self.horizontalGroupBox_options.setLayout(verticalbox_options)
        self.horizontalGroupBox_options.resize(360, 80)
        self.horizontalGroupBox_options.move(20, 110)

    def startup_settings(self):
        startup_state = self.checkbox_startup.isChecked()
        settings.setValue("startup_state", startup_state)
        print("startup state is ", settings.value("startup_state", type=bool))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    screen = Window()
    screen.show()
    app.exec()

Answered outside of stackoverflow at Python Discord by user Numerlor

onefile works by extracting it's contents to a temp directory, that has its path stored in sys._MEIPASS . So you setting the values in resources.config_ini only changes the extracted file, which is removed after you close the program

qt has a bunch of paths under QtCore.QStandardPaths.writableLocation that might be where you want to store config, like QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppConfigLocation) which returns .../appdata/local/{org}/{app}

These lines are added at the begging of the GUI.

# This return .../appdata/local
local_path = QStandardPaths.writableLocation(QStandardPaths.AppConfigLocation) 
# Make directory for my program
os.makedirs(local_path + "\\" + "FilesOrganizer", exist_ok=True) 
# Making config.ini file.
config_path = local_path + "\\" + "FilesOrganizer" + "\\" + "config.ini" 
settings = QSettings(config_path, QSettings.IniFormat)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM