22 |
22 |
23 class PyInstallerExecDialog(QDialog, Ui_PyInstallerExecDialog): |
23 class PyInstallerExecDialog(QDialog, Ui_PyInstallerExecDialog): |
24 """ |
24 """ |
25 Class implementing a dialog to show the output of the |
25 Class implementing a dialog to show the output of the |
26 pyinstaller/pyi-makespec process. |
26 pyinstaller/pyi-makespec process. |
27 |
27 |
28 This class starts a QProcess and displays a dialog that |
28 This class starts a QProcess and displays a dialog that |
29 shows the output of the packager command process. |
29 shows the output of the packager command process. |
30 """ |
30 """ |
|
31 |
31 def __init__(self, cmdname, parent=None): |
32 def __init__(self, cmdname, parent=None): |
32 """ |
33 """ |
33 Constructor |
34 Constructor |
34 |
35 |
35 @param cmdname name of the packager |
36 @param cmdname name of the packager |
36 @type str |
37 @type str |
37 @param parent reference to the parent widget |
38 @param parent reference to the parent widget |
38 @type QWidget |
39 @type QWidget |
39 """ |
40 """ |
40 super().__init__(parent) |
41 super().__init__(parent) |
41 self.setupUi(self) |
42 self.setupUi(self) |
42 |
43 |
43 self.buttonBox.button( |
44 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False) |
44 QDialogButtonBox.StandardButton.Close).setEnabled(False) |
45 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
45 self.buttonBox.button( |
46 |
46 QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
|
47 |
|
48 self.__process = None |
47 self.__process = None |
49 self.__cmdname = cmdname # used for several outputs |
48 self.__cmdname = cmdname # used for several outputs |
50 |
49 |
51 def start(self, args, parms, project, script): |
50 def start(self, args, parms, project, script): |
52 """ |
51 """ |
53 Public slot to start the packager command. |
52 Public slot to start the packager command. |
54 |
53 |
55 @param args command line arguments for packager program |
54 @param args command line arguments for packager program |
56 @type list of str |
55 @type list of str |
57 @param parms parameters got from the config dialog |
56 @param parms parameters got from the config dialog |
58 @type dict |
57 @type dict |
59 @param project reference to the project object |
58 @param project reference to the project object |
63 @type str |
62 @type str |
64 @return flag indicating the successful start of the process |
63 @return flag indicating the successful start of the process |
65 @rtype bool |
64 @rtype bool |
66 """ |
65 """ |
67 self.__project = project |
66 self.__project = project |
68 |
67 |
69 if not os.path.isabs(script): |
68 if not os.path.isabs(script): |
70 # assume relative paths are relative to the project directory |
69 # assume relative paths are relative to the project directory |
71 script = os.path.join(self.__project.getProjectPath(), script) |
70 script = os.path.join(self.__project.getProjectPath(), script) |
72 dname = os.path.dirname(script) |
71 dname = os.path.dirname(script) |
73 self.__script = os.path.basename(script) |
72 self.__script = os.path.basename(script) |
74 |
73 |
75 self.contents.clear() |
74 self.contents.clear() |
76 |
75 |
77 args.append(self.__script) |
76 args.append(self.__script) |
78 |
77 |
79 self.__process = QProcess() |
78 self.__process = QProcess() |
80 self.__process.setWorkingDirectory(dname) |
79 self.__process.setWorkingDirectory(dname) |
81 |
80 |
82 self.__process.readyReadStandardOutput.connect(self.__readStdout) |
81 self.__process.readyReadStandardOutput.connect(self.__readStdout) |
83 self.__process.readyReadStandardError.connect(self.__readStderr) |
82 self.__process.readyReadStandardError.connect(self.__readStderr) |
84 self.__process.finished.connect(self.__finishedProcess) |
83 self.__process.finished.connect(self.__finishedProcess) |
85 |
84 |
86 self.setWindowTitle(self.tr('{0} - {1}').format( |
85 self.setWindowTitle(self.tr("{0} - {1}").format(self.__cmdname, script)) |
87 self.__cmdname, script)) |
86 self.contents.insertPlainText( |
88 self.contents.insertPlainText("{0} {1}\n\n".format( |
87 "{0} {1}\n\n".format(" ".join(args), os.path.join(dname, self.__script)) |
89 ' '.join(args), os.path.join(dname, self.__script))) |
88 ) |
90 self.contents.ensureCursorVisible() |
89 self.contents.ensureCursorVisible() |
91 |
90 |
92 program = args.pop(0) |
91 program = args.pop(0) |
93 self.__process.start(program, args) |
92 self.__process.start(program, args) |
94 procStarted = self.__process.waitForStarted() |
93 procStarted = self.__process.waitForStarted() |
95 if not procStarted: |
94 if not procStarted: |
96 EricMessageBox.critical( |
95 EricMessageBox.critical( |
97 self, |
96 self, |
98 self.tr('Process Generation Error'), |
97 self.tr("Process Generation Error"), |
99 self.tr( |
98 self.tr( |
100 'The process {0} could not be started. ' |
99 "The process {0} could not be started. " |
101 'Ensure, that it is in the search path.' |
100 "Ensure, that it is in the search path." |
102 ).format(program)) |
101 ).format(program), |
|
102 ) |
103 return procStarted |
103 return procStarted |
104 |
104 |
105 @pyqtSlot(QAbstractButton) |
105 @pyqtSlot(QAbstractButton) |
106 def on_buttonBox_clicked(self, button): |
106 def on_buttonBox_clicked(self, button): |
107 """ |
107 """ |
108 Private slot called by a button of the button box clicked. |
108 Private slot called by a button of the button box clicked. |
109 |
109 |
110 @param button button that was clicked |
110 @param button button that was clicked |
111 @type QAbstractButton |
111 @type QAbstractButton |
112 """ |
112 """ |
113 if button == self.buttonBox.button( |
113 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close): |
114 QDialogButtonBox.StandardButton.Close |
|
115 ): |
|
116 self.accept() |
114 self.accept() |
117 elif button == self.buttonBox.button( |
115 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel): |
118 QDialogButtonBox.StandardButton.Cancel |
|
119 ): |
|
120 self.__finish() |
116 self.__finish() |
121 |
117 |
122 def __finish(self): |
118 def __finish(self): |
123 """ |
119 """ |
124 Private slot called when the process was canceled by the user. |
120 Private slot called when the process was canceled by the user. |
125 |
121 |
126 It is called when the process finished or |
122 It is called when the process finished or |
127 the user pressed the cancel button. |
123 the user pressed the cancel button. |
128 """ |
124 """ |
129 if self.__process is not None: |
125 if self.__process is not None: |
130 self.__process.disconnect(self.__finishedProcess) |
126 self.__process.disconnect(self.__finishedProcess) |
131 self.__process.terminate() |
127 self.__process.terminate() |
132 QTimer.singleShot(2000, self.__process.kill) |
128 QTimer.singleShot(2000, self.__process.kill) |
133 self.__process.waitForFinished(3000) |
129 self.__process.waitForFinished(3000) |
134 self.__process = None |
130 self.__process = None |
135 |
131 |
136 self.contents.insertPlainText( |
132 self.contents.insertPlainText( |
137 self.tr('\n{0} aborted.\n').format(self.__cmdname)) |
133 self.tr("\n{0} aborted.\n").format(self.__cmdname) |
138 |
134 ) |
|
135 |
139 self.__enableButtons() |
136 self.__enableButtons() |
140 |
137 |
141 def __finishedProcess(self): |
138 def __finishedProcess(self): |
142 """ |
139 """ |
143 Private slot called when the process finished. |
140 Private slot called when the process finished. |
144 |
141 |
145 It is called when the process finished or |
142 It is called when the process finished or |
146 the user pressed the cancel button. |
143 the user pressed the cancel button. |
147 """ |
144 """ |
148 if self.__process.exitStatus() == QProcess.ExitStatus.NormalExit: |
145 if self.__process.exitStatus() == QProcess.ExitStatus.NormalExit: |
149 # add the spec file to the project |
146 # add the spec file to the project |
150 self.__project.addToOthers( |
147 self.__project.addToOthers(os.path.splitext(self.__script)[0] + ".spec") |
151 os.path.splitext(self.__script)[0] + ".spec") |
148 |
152 |
|
153 self.__process = None |
149 self.__process = None |
154 |
150 |
155 self.contents.insertPlainText( |
151 self.contents.insertPlainText( |
156 self.tr('\n{0} finished.\n').format(self.__cmdname)) |
152 self.tr("\n{0} finished.\n").format(self.__cmdname) |
157 |
153 ) |
|
154 |
158 self.__enableButtons() |
155 self.__enableButtons() |
159 |
156 |
160 def __enableButtons(self): |
157 def __enableButtons(self): |
161 """ |
158 """ |
162 Private slot called when all processes finished. |
159 Private slot called when all processes finished. |
163 |
160 |
164 It is called when the process finished or |
161 It is called when the process finished or |
165 the user pressed the cancel button. |
162 the user pressed the cancel button. |
166 """ |
163 """ |
167 self.buttonBox.button( |
164 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True) |
168 QDialogButtonBox.StandardButton.Close).setEnabled(True) |
165 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
169 self.buttonBox.button( |
166 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) |
170 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
|
171 self.buttonBox.button( |
|
172 QDialogButtonBox.StandardButton.Close).setDefault(True) |
|
173 self.contents.ensureCursorVisible() |
167 self.contents.ensureCursorVisible() |
174 |
168 |
175 def __readStdout(self): |
169 def __readStdout(self): |
176 """ |
170 """ |
177 Private slot to handle the readyReadStandardOutput signal. |
171 Private slot to handle the readyReadStandardOutput signal. |
178 |
172 |
179 It reads the output of the process, formats it and inserts it into |
173 It reads the output of the process, formats it and inserts it into |
180 the contents pane. |
174 the contents pane. |
181 """ |
175 """ |
182 self.__process.setReadChannel(QProcess.ProcessChannel.StandardOutput) |
176 self.__process.setReadChannel(QProcess.ProcessChannel.StandardOutput) |
183 |
177 |
184 while self.__process.canReadLine(): |
178 while self.__process.canReadLine(): |
185 s = str(self.__process.readAllStandardOutput(), |
179 s = str( |
186 Preferences.getSystem("IOEncoding"), |
180 self.__process.readAllStandardOutput(), |
187 'replace') |
181 Preferences.getSystem("IOEncoding"), |
|
182 "replace", |
|
183 ) |
188 self.contents.insertPlainText(s) |
184 self.contents.insertPlainText(s) |
189 self.contents.ensureCursorVisible() |
185 self.contents.ensureCursorVisible() |
190 |
186 |
191 def __readStderr(self): |
187 def __readStderr(self): |
192 """ |
188 """ |
193 Private slot to handle the readyReadStandardError signal. |
189 Private slot to handle the readyReadStandardError signal. |
194 |
190 |
195 It reads the error output of the process and inserts it into the |
191 It reads the error output of the process and inserts it into the |
196 error pane. |
192 error pane. |
197 """ |
193 """ |
198 self.__process.setReadChannel(QProcess.ProcessChannel.StandardError) |
194 self.__process.setReadChannel(QProcess.ProcessChannel.StandardError) |
199 |
195 |
200 while self.__process.canReadLine(): |
196 while self.__process.canReadLine(): |
201 s = str(self.__process.readAllStandardError(), |
197 s = str( |
202 Preferences.getSystem("IOEncoding"), |
198 self.__process.readAllStandardError(), |
203 'replace') |
199 Preferences.getSystem("IOEncoding"), |
|
200 "replace", |
|
201 ) |
204 self.contents.insertPlainText(s) |
202 self.contents.insertPlainText(s) |
205 self.contents.ensureCursorVisible() |
203 self.contents.ensureCursorVisible() |