PyInstallerInterface/PyInstallerConfigDialog.py

branch
eric7
changeset 46
ccd14067e6a2
parent 43
01ce3d6f7a07
child 47
3b9805bff70c
equal deleted inserted replaced
45:2d3b599c85b1 46:ccd14067e6a2
22 class PyInstallerConfigDialog(QDialog, Ui_PyInstallerConfigDialog): 22 class PyInstallerConfigDialog(QDialog, Ui_PyInstallerConfigDialog):
23 """ 23 """
24 Class implementing a dialog to enter the parameters for pyinstaller 24 Class implementing a dialog to enter the parameters for pyinstaller
25 and pyi-makespec. 25 and pyi-makespec.
26 """ 26 """
27 def __init__(self, project, executables, params=None, mode="installer", 27
28 parent=None): 28 def __init__(
29 self, project, executables, params=None, mode="installer", parent=None
30 ):
29 """ 31 """
30 Constructor 32 Constructor
31 33
32 @param project reference to the project object 34 @param project reference to the project object
33 @type Project.Project 35 @type Project.Project
34 @param executables names of the pyinstaller executables 36 @param executables names of the pyinstaller executables
35 @type list of str 37 @type list of str
36 @param params parameters to set in the dialog 38 @param params parameters to set in the dialog
40 @param parent reference to the parent widget 42 @param parent reference to the parent widget
41 @type QWidget 43 @type QWidget
42 """ 44 """
43 super().__init__(parent) 45 super().__init__(parent)
44 self.setupUi(self) 46 self.setupUi(self)
45 47
46 self.__project = project 48 self.__project = project
47 self.__mode = mode 49 self.__mode = mode
48 50
49 self.inputFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) 51 self.inputFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
50 self.inputFilePicker.setDefaultDirectory( 52 self.inputFilePicker.setDefaultDirectory(self.__project.getProjectPath())
51 self.__project.getProjectPath())
52 if self.__mode == "installer": 53 if self.__mode == "installer":
53 self.inputFilePicker.setFilters(self.tr( 54 self.inputFilePicker.setFilters(
54 "Python Files (*.py *.py3);;" 55 self.tr(
55 "Python GUI Files (*.pyw *.pyw3);;" 56 "Python Files (*.py *.py3);;"
56 "Spec Files (*.spec);;" 57 "Python GUI Files (*.pyw *.pyw3);;"
57 "All Files (*)" 58 "Spec Files (*.spec);;"
58 )) 59 "All Files (*)"
60 )
61 )
59 elif self.__mode == "spec": 62 elif self.__mode == "spec":
60 self.inputFilePicker.setFilters(self.tr( 63 self.inputFilePicker.setFilters(
61 "Python Files (*.py *.py3);;" 64 self.tr(
62 "Python GUI Files (*.pyw *.pyw3);;" 65 "Python Files (*.py *.py3);;"
63 "All Files (*)" 66 "Python GUI Files (*.pyw *.pyw3);;"
64 )) 67 "All Files (*)"
65 68 )
69 )
70
66 self.executableCombo.addItems(executables) 71 self.executableCombo.addItems(executables)
67 72
68 if not bool(project.getMainScript()): 73 if not bool(project.getMainScript()):
69 # no main script defined 74 # no main script defined
70 self.selectedScriptButton.setChecked(True) 75 self.selectedScriptButton.setChecked(True)
71 self.mainScriptButton.setEnabled(False) 76 self.mainScriptButton.setEnabled(False)
72 77
73 self.iconFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) 78 self.iconFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
74 self.iconFilePicker.setDefaultDirectory( 79 self.iconFilePicker.setDefaultDirectory(self.__project.getProjectPath())
75 self.__project.getProjectPath())
76 if Globals.isMacPlatform(): 80 if Globals.isMacPlatform():
77 self.iconFilePicker.setFilters(self.tr( 81 self.iconFilePicker.setFilters(
78 "Icon Files (*.icns);;" 82 self.tr("Icon Files (*.icns);;" "All Files (*)")
79 "All Files (*)" 83 )
80 ))
81 elif Globals.isWindowsPlatform(): 84 elif Globals.isWindowsPlatform():
82 self.iconFilePicker.setFilters(self.tr( 85 self.iconFilePicker.setFilters(
83 "Icon Files (*.ico);;" 86 self.tr(
84 "Executable Files (*.exe);;" 87 "Icon Files (*.ico);;" "Executable Files (*.exe);;" "All Files (*)"
85 "All Files (*)" 88 )
86 )) 89 )
87 90
88 # disable platform specific tabs 91 # disable platform specific tabs
89 self.tabWidget.setTabEnabled( 92 self.tabWidget.setTabEnabled(
90 self.tabWidget.indexOf(self.windowsMacTab), 93 self.tabWidget.indexOf(self.windowsMacTab),
91 Globals.isMacPlatform() or Globals.isWindowsPlatform()) 94 Globals.isMacPlatform() or Globals.isWindowsPlatform(),
95 )
92 self.tabWidget.setTabEnabled( 96 self.tabWidget.setTabEnabled(
93 self.tabWidget.indexOf(self.macTab), 97 self.tabWidget.indexOf(self.macTab), Globals.isMacPlatform()
94 Globals.isMacPlatform()) 98 )
95 99
96 self.__initializeDefaults() 100 self.__initializeDefaults()
97 101
98 # get a copy of the defaults to store the user settings 102 # get a copy of the defaults to store the user settings
99 self.__parameters = copy.deepcopy(self.__defaults) 103 self.__parameters = copy.deepcopy(self.__defaults)
100 104
101 # combine it with the values of params 105 # combine it with the values of params
102 if params is not None: 106 if params is not None:
103 self.__parameters.update(params) 107 self.__parameters.update(params)
104 108
105 # initialize general tab 109 # initialize general tab
106 if mode == "installer" and bool(self.__parameters["pyinstaller"]): 110 if mode == "installer" and bool(self.__parameters["pyinstaller"]):
107 self.executableCombo.setCurrentIndex( 111 self.executableCombo.setCurrentIndex(
108 self.executableCombo.findText( 112 self.executableCombo.findText(self.__parameters["pyinstaller"])
109 self.__parameters["pyinstaller"])) 113 )
110 elif mode == "spec" and bool(self.__parameters["pyi-makespec"]): 114 elif mode == "spec" and bool(self.__parameters["pyi-makespec"]):
111 self.executableCombo.setCurrentIndex( 115 self.executableCombo.setCurrentIndex(
112 self.executableCombo.findText( 116 self.executableCombo.findText(self.__parameters["pyi-makespec"])
113 self.__parameters["pyi-makespec"])) 117 )
114 if self.__parameters["mainscript"]: 118 if self.__parameters["mainscript"]:
115 self.mainScriptButton.setChecked(True) 119 self.mainScriptButton.setChecked(True)
116 else: 120 else:
117 self.selectedScriptButton.setChecked(True) 121 self.selectedScriptButton.setChecked(True)
118 self.inputFilePicker.setText(self.__parameters["inputFile"]) 122 self.inputFilePicker.setText(self.__parameters["inputFile"])
121 else: 125 else:
122 self.oneFileButton.setChecked(True) 126 self.oneFileButton.setChecked(True)
123 self.nameEdit.setText(self.__parameters["name"]) 127 self.nameEdit.setText(self.__parameters["name"])
124 self.keyEdit.setText(self.__parameters["encryptionKey"]) 128 self.keyEdit.setText(self.__parameters["encryptionKey"])
125 self.cleanCheckBox.setChecked(self.__parameters["cleanBeforeBuilding"]) 129 self.cleanCheckBox.setChecked(self.__parameters["cleanBeforeBuilding"])
126 130
127 # initialize Windows and macOS tab 131 # initialize Windows and macOS tab
128 if self.__parameters["consoleApplication"]: 132 if self.__parameters["consoleApplication"]:
129 self.consoleButton.setChecked(True) 133 self.consoleButton.setChecked(True)
130 else: 134 else:
131 self.windowedButton.setChecked(True) 135 self.windowedButton.setChecked(True)
132 self.iconFilePicker.setText(self.__parameters["iconFile"]) 136 self.iconFilePicker.setText(self.__parameters["iconFile"])
133 self.iconIdEdit.setText(self.__parameters["iconId"]) 137 self.iconIdEdit.setText(self.__parameters["iconId"])
134 138
135 # initialize maxOS specific tab 139 # initialize maxOS specific tab
136 self.bundleIdentifierEdit.setText( 140 self.bundleIdentifierEdit.setText(self.__parameters["bundleIdentifier"])
137 self.__parameters["bundleIdentifier"]) 141
138 142 self.__updateOkButton()
139 self.__updateOkButton() 143
140
141 msh = self.minimumSizeHint() 144 msh = self.minimumSizeHint()
142 self.resize(max(self.width(), msh.width()), msh.height()) 145 self.resize(max(self.width(), msh.width()), msh.height())
143 146
144 def __initializeDefaults(self): 147 def __initializeDefaults(self):
145 """ 148 """
146 Private method to set the default values. 149 Private method to set the default values.
147 150
148 These are needed later on to generate the command line parameters. 151 These are needed later on to generate the command line parameters.
149 """ 152 """
150 self.__defaults = { 153 self.__defaults = {
151 # general options 154 # general options
152 "pyinstaller": "", 155 "pyinstaller": "",
155 "inputFile": "", 158 "inputFile": "",
156 "oneDirectory": True, 159 "oneDirectory": True,
157 "name": "", 160 "name": "",
158 "encryptionKey": "", 161 "encryptionKey": "",
159 "cleanBeforeBuilding": False, 162 "cleanBeforeBuilding": False,
160
161 # Windows and macOS options 163 # Windows and macOS options
162 "consoleApplication": True, 164 "consoleApplication": True,
163 "iconFile": "", 165 "iconFile": "",
164 "iconId": "", 166 "iconId": "",
165
166 # macOS specific options 167 # macOS specific options
167 "bundleIdentifier": "", 168 "bundleIdentifier": "",
168 } 169 }
169 170
170 def generateParameters(self): 171 def generateParameters(self):
171 """ 172 """
172 Public method that generates the command line parameters. 173 Public method that generates the command line parameters.
173 174
174 It generates a list of strings to be used to set the QProcess arguments 175 It generates a list of strings to be used to set the QProcess arguments
175 for the pyinstaller/pyi-makespec call and a list containing the non 176 for the pyinstaller/pyi-makespec call and a list containing the non
176 default parameters. The second list can be passed back upon object 177 default parameters. The second list can be passed back upon object
177 generation to overwrite the default settings. 178 generation to overwrite the default settings.
178 179
179 @return a tuple of the command line parameters, non default parameters 180 @return a tuple of the command line parameters, non default parameters
180 and the script path 181 and the script path
181 @rtype tuple of (list of str, dict, str) 182 @rtype tuple of (list of str, dict, str)
182 """ 183 """
183 parms = {} 184 parms = {}
184 args = [] 185 args = []
185 186
186 # 1. the program name 187 # 1. the program name
187 if self.__mode == "installer": 188 if self.__mode == "installer":
188 args.append(self.__parameters["pyinstaller"]) 189 args.append(self.__parameters["pyinstaller"])
189 parms["pyinstaller"] = self.__parameters["pyinstaller"] 190 parms["pyinstaller"] = self.__parameters["pyinstaller"]
190 elif self.__mode == "spec": 191 elif self.__mode == "spec":
191 args.append(self.__parameters["pyi-makespec"]) 192 args.append(self.__parameters["pyi-makespec"])
192 parms["pyi-makespec"] = self.__parameters["pyi-makespec"] 193 parms["pyi-makespec"] = self.__parameters["pyi-makespec"]
193 194
194 # 2. the commandline options 195 # 2. the commandline options
195 # 2.1 general options, input 196 # 2.1 general options, input
196 if not self.__parameters["mainscript"]: 197 if not self.__parameters["mainscript"]:
197 parms["mainscript"] = False 198 parms["mainscript"] = False
198 parms["inputFile"] = self.__parameters["inputFile"] 199 parms["inputFile"] = self.__parameters["inputFile"]
199 200
200 runWithSpec = self.__parameters["inputFile"].endswith(".spec") 201 runWithSpec = self.__parameters["inputFile"].endswith(".spec")
201 if not runWithSpec: 202 if not runWithSpec:
202 # 2.2 general options, part 1 203 # 2.2 general options, part 1
203 if not self.__parameters["oneDirectory"]: 204 if not self.__parameters["oneDirectory"]:
204 parms["oneDirectory"] = self.__parameters["oneDirectory"] 205 parms["oneDirectory"] = self.__parameters["oneDirectory"]
205 args.append("--onefile") 206 args.append("--onefile")
206 if self.__parameters["name"] != self.__defaults["name"]: 207 if self.__parameters["name"] != self.__defaults["name"]:
207 parms["name"] = self.__parameters["name"] 208 parms["name"] = self.__parameters["name"]
208 args.append("--name") 209 args.append("--name")
209 args.append(self.__parameters["name"]) 210 args.append(self.__parameters["name"])
210 if ( 211 if self.__parameters["encryptionKey"] != self.__defaults["encryptionKey"]:
211 self.__parameters["encryptionKey"] !=
212 self.__defaults["encryptionKey"]
213 ):
214 parms["encryptionKey"] = self.__parameters["encryptionKey"] 212 parms["encryptionKey"] = self.__parameters["encryptionKey"]
215 args.append("--key") 213 args.append("--key")
216 args.append(self.__parameters["encryptionKey"]) 214 args.append(self.__parameters["encryptionKey"])
217 215
218 # 2.3 Windows and macOS options 216 # 2.3 Windows and macOS options
219 if ( 217 if (
220 self.__parameters["consoleApplication"] != 218 self.__parameters["consoleApplication"]
221 self.__defaults["consoleApplication"] 219 != self.__defaults["consoleApplication"]
222 ): 220 ):
223 parms["consoleApplication"] = ( 221 parms["consoleApplication"] = self.__parameters["consoleApplication"]
224 self.__parameters["consoleApplication"]
225 )
226 args.append("--windowed") 222 args.append("--windowed")
227 if self.__parameters["iconFile"] != self.__defaults["iconFile"]: 223 if self.__parameters["iconFile"] != self.__defaults["iconFile"]:
228 parms["iconFile"] = self.__parameters["iconFile"] 224 parms["iconFile"] = self.__parameters["iconFile"]
229 parms["iconId"] = self.__parameters["iconId"] 225 parms["iconId"] = self.__parameters["iconId"]
230 args.append("--icon") 226 args.append("--icon")
231 if self.__parameters["iconFile"].endswith(".exe"): 227 if self.__parameters["iconFile"].endswith(".exe"):
232 if bool(self.__parameters["iconId"]): 228 if bool(self.__parameters["iconId"]):
233 iconId = self.__parameters["iconId"] 229 iconId = self.__parameters["iconId"]
234 else: 230 else:
235 iconId = "0" 231 iconId = "0"
236 args.append("{0},{1}".format( 232 args.append("{0},{1}".format(self.__parameters["iconFile"], iconId))
237 self.__parameters["iconFile"], iconId))
238 else: 233 else:
239 args.append(self.__parameters["iconFile"]) 234 args.append(self.__parameters["iconFile"])
240 235
241 # 2.4 macOS specific options 236 # 2.4 macOS specific options
242 if ( 237 if (
243 self.__parameters["bundleIdentifier"] != 238 self.__parameters["bundleIdentifier"]
244 self.__defaults["bundleIdentifier"] 239 != self.__defaults["bundleIdentifier"]
245 ): 240 ):
246 parms["bundleIdentifier"] = ( 241 parms["bundleIdentifier"] = self.__parameters["bundleIdentifier"]
247 self.__parameters["bundleIdentifier"]
248 )
249 args.append("--osx-bundle-identifier") 242 args.append("--osx-bundle-identifier")
250 args.append(self.__parameters["bundleIdentifier"]) 243 args.append(self.__parameters["bundleIdentifier"])
251 244
252 # 2.5 general options, part 2 245 # 2.5 general options, part 2
253 if ( 246 if (
254 self.__parameters["cleanBeforeBuilding"] != 247 self.__parameters["cleanBeforeBuilding"]
255 self.__defaults["cleanBeforeBuilding"] 248 != self.__defaults["cleanBeforeBuilding"]
256 ): 249 ):
257 parms["cleanBeforeBuilding"] = ( 250 parms["cleanBeforeBuilding"] = self.__parameters["cleanBeforeBuilding"]
258 self.__parameters["cleanBeforeBuilding"]
259 )
260 args.append("--clean") 251 args.append("--clean")
261 252
262 # 3. always add these arguments 253 # 3. always add these arguments
263 if self.__mode == "installer": 254 if self.__mode == "installer":
264 args.append("--noconfirm") # don't ask the user 255 args.append("--noconfirm") # don't ask the user
265 256
266 # determine the script to be processed 257 # determine the script to be processed
267 script = ( 258 script = (
268 self.__project.getMainScript() 259 self.__project.getMainScript()
269 if self.__parameters["mainscript"] else 260 if self.__parameters["mainscript"]
270 self.__parameters["inputFile"] 261 else self.__parameters["inputFile"]
271 ) 262 )
272 263
273 return args, parms, script 264 return args, parms, script
274 265
275 def accept(self): 266 def accept(self):
276 """ 267 """
277 Public method called by the Ok button. 268 Public method called by the Ok button.
278 269
279 It saves the values in the parameters dictionary. 270 It saves the values in the parameters dictionary.
280 """ 271 """
281 # get data of general tab 272 # get data of general tab
282 if self.__mode == "installer": 273 if self.__mode == "installer":
283 self.__parameters["pyinstaller"] = ( 274 self.__parameters["pyinstaller"] = self.executableCombo.currentText()
284 self.executableCombo.currentText()
285 )
286 elif self.__mode == "spec": 275 elif self.__mode == "spec":
287 self.__parameters["pyi-makespec"] = ( 276 self.__parameters["pyi-makespec"] = self.executableCombo.currentText()
288 self.executableCombo.currentText()
289 )
290 self.__parameters["mainscript"] = self.mainScriptButton.isChecked() 277 self.__parameters["mainscript"] = self.mainScriptButton.isChecked()
291 self.__parameters["inputFile"] = self.inputFilePicker.text() 278 self.__parameters["inputFile"] = self.inputFilePicker.text()
292 self.__parameters["oneDirectory"] = self.oneDirButton.isChecked() 279 self.__parameters["oneDirectory"] = self.oneDirButton.isChecked()
293 self.__parameters["name"] = self.nameEdit.text() 280 self.__parameters["name"] = self.nameEdit.text()
294 self.__parameters["encryptionKey"] = self.keyEdit.text() 281 self.__parameters["encryptionKey"] = self.keyEdit.text()
295 self.__parameters["cleanBeforeBuilding"] = ( 282 self.__parameters["cleanBeforeBuilding"] = self.cleanCheckBox.isChecked()
296 self.cleanCheckBox.isChecked() 283
297 )
298
299 # get data of Windows and macOS tab 284 # get data of Windows and macOS tab
300 self.__parameters["consoleApplication"] = ( 285 self.__parameters["consoleApplication"] = self.consoleButton.isChecked()
301 self.consoleButton.isChecked()
302 )
303 self.__parameters["iconFile"] = self.iconFilePicker.text() 286 self.__parameters["iconFile"] = self.iconFilePicker.text()
304 self.__parameters["iconId"] = self.iconIdEdit.text() 287 self.__parameters["iconId"] = self.iconIdEdit.text()
305 288
306 # get data of macOS specific tab 289 # get data of macOS specific tab
307 self.__parameters["bundleIdentifier"] = ( 290 self.__parameters["bundleIdentifier"] = self.bundleIdentifierEdit.text()
308 self.bundleIdentifierEdit.text()
309 )
310 291
311 # call the accept slot of the base class 292 # call the accept slot of the base class
312 super().accept() 293 super().accept()
313 294
314 def __updateOkButton(self): 295 def __updateOkButton(self):
315 """ 296 """
316 Private method to update the enabled state of the OK button. 297 Private method to update the enabled state of the OK button.
317 """ 298 """
318 enable = True 299 enable = True
319 300
320 # If not to be run with the project main script, a script or 301 # If not to be run with the project main script, a script or
321 # spec file must be selected. 302 # spec file must be selected.
322 if ( 303 if self.selectedScriptButton.isChecked() and not bool(
323 self.selectedScriptButton.isChecked() and 304 self.inputFilePicker.text()
324 not bool(self.inputFilePicker.text())
325 ): 305 ):
326 enable = False 306 enable = False
327 307
328 # If the icon shall be picked from a .exe file, an icon ID 308 # If the icon shall be picked from a .exe file, an icon ID
329 # must be entered (Windows only). 309 # must be entered (Windows only).
330 if ( 310 if self.iconFilePicker.text().endswith(".exe") and not bool(
331 self.iconFilePicker.text().endswith(".exe") and 311 self.iconIdEdit.text()
332 not bool(self.iconIdEdit.text())
333 ): 312 ):
334 enable = False 313 enable = False
335 314
336 self.buttonBox.button( 315 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable)
337 QDialogButtonBox.StandardButton.Ok).setEnabled(enable) 316
338
339 @pyqtSlot(bool) 317 @pyqtSlot(bool)
340 def on_selectedScriptButton_toggled(self, checked): 318 def on_selectedScriptButton_toggled(self, checked):
341 """ 319 """
342 Private slot to handle changes of the radio button state. 320 Private slot to handle changes of the radio button state.
343 321
344 @param checked state of the radio button 322 @param checked state of the radio button
345 @type bool 323 @type bool
346 """ 324 """
347 self.__updateOkButton() 325 self.__updateOkButton()
348 326
349 @pyqtSlot(str) 327 @pyqtSlot(str)
350 def on_inputFilePicker_textChanged(self, txt): 328 def on_inputFilePicker_textChanged(self, txt):
351 """ 329 """
352 Private slot to handle changes of the input file. 330 Private slot to handle changes of the input file.
353 331
354 @param txt text of the file edit 332 @param txt text of the file edit
355 @type str 333 @type str
356 """ 334 """
357 self.__updateOkButton() 335 self.__updateOkButton()
358 336
359 @pyqtSlot(str) 337 @pyqtSlot(str)
360 def on_iconFilePicker_textChanged(self, txt): 338 def on_iconFilePicker_textChanged(self, txt):
361 """ 339 """
362 Private slot to handle changes of the icon file. 340 Private slot to handle changes of the icon file.
363 341
364 @param txt text of the file edit 342 @param txt text of the file edit
365 @type str 343 @type str
366 """ 344 """
367 self.iconIdEdit.setEnabled(txt.endswith(".exe")) 345 self.iconIdEdit.setEnabled(txt.endswith(".exe"))
368 self.__updateOkButton() 346 self.__updateOkButton()
369 347
370 @pyqtSlot(str) 348 @pyqtSlot(str)
371 def on_iconIdEdit_textChanged(self, txt): 349 def on_iconIdEdit_textChanged(self, txt):
372 """ 350 """
373 Private slot to handle changes of the icon ID. 351 Private slot to handle changes of the icon ID.
374 352
375 @param txt iconID 353 @param txt iconID
376 @type str 354 @type str
377 """ 355 """
378 self.__updateOkButton() 356 self.__updateOkButton()

eric ide

mercurial