ProjectDjango/DjangoDialog.py

branch
eric7
changeset 172
ea7980ded4f3
parent 169
b8f263e05c39
child 175
30cb5e553e7e
equal deleted inserted replaced
171:af99f0984f20 172:ea7980ded4f3
7 Module implementing a dialog starting a process and showing its output. 7 Module implementing a dialog starting a process and showing its output.
8 """ 8 """
9 9
10 import os 10 import os
11 11
12 from PyQt5.QtCore import pyqtSlot, QProcess, QTimer, QFileInfo 12 from PyQt6.QtCore import pyqtSlot, QProcess, QTimer, QFileInfo
13 from PyQt5.QtWidgets import ( 13 from PyQt6.QtWidgets import (
14 QDialog, QDialogButtonBox, QAbstractButton, QTextEdit, QLineEdit 14 QDialog, QDialogButtonBox, QAbstractButton, QTextEdit, QLineEdit
15 ) 15 )
16 16
17 from E5Gui import E5MessageBox, E5FileDialog 17 from EricWidgets import EricMessageBox, EricFileDialog
18 18
19 from .Ui_DjangoDialog import Ui_DjangoDialog 19 from .Ui_DjangoDialog import Ui_DjangoDialog
20 20
21 import Preferences 21 import Preferences
22 22
36 saveFilters=None, showInput=False, 36 saveFilters=None, showInput=False,
37 parent=None): 37 parent=None):
38 """ 38 """
39 Constructor 39 Constructor
40 40
41 @param text text to be shown by the label (string) 41 @param text text to be shown by the label
42 @keyparam fixed flag indicating a fixed font should be used (boolean) 42 @type str
43 @keyparam linewrap flag indicating to wrap long lines (boolean) 43 @param fixed flag indicating a fixed font should be used
44 @keyparam msgSuccess optional string to show upon successful execution 44 @type bool
45 (string) 45 @param linewrap flag indicating to wrap long lines
46 @keyparam msgError optional string to show upon unsuccessful execution 46 @type bool
47 (string) 47 @param msgSuccess optional string to show upon successful execution
48 @keyparam saveFilters filename filter string (string) 48 @type str
49 @keyparam showInput flag indicating to show the input widgets (bool) 49 @param msgError optional string to show upon unsuccessful execution
50 @keyparam parent parent widget (QWidget) 50 @type str
51 @param saveFilters filename filter string
52 @type str
53 @param showInput flag indicating to show the input widgets
54 @type bool
55 @param parent parent widget
56 @type QWidget
51 """ 57 """
52 super().__init__(parent) 58 super().__init__(parent)
53 self.setupUi(self) 59 self.setupUi(self)
54 60
55 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) 61 self.buttonBox.button(
56 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) 62 QDialogButtonBox.StandardButton.Close).setEnabled(False)
57 self.buttonBox.button(QDialogButtonBox.Save).setEnabled(False) 63 self.buttonBox.button(
64 QDialogButtonBox.StandardButton.Cancel).setDefault(True)
65 self.buttonBox.button(
66 QDialogButtonBox.StandardButton.Save).setEnabled(False)
58 if saveFilters is None: 67 if saveFilters is None:
59 self.buttonBox.button(QDialogButtonBox.Save).setHidden(True) 68 self.buttonBox.button(
69 QDialogButtonBox.StandardButton.Save).setHidden(True)
60 70
61 self.ioEncoding = Preferences.getSystem("IOEncoding") 71 self.ioEncoding = Preferences.getSystem("IOEncoding")
62 72
63 self.proc = None 73 self.proc = None
64 self.argsLists = [] 74 self.argsLists = []
77 self.resultbox.setFontFamily("Lucida Console") 87 self.resultbox.setFontFamily("Lucida Console")
78 else: 88 else:
79 self.resultbox.setFontFamily("Monospace") 89 self.resultbox.setFontFamily("Monospace")
80 90
81 if not linewrap: 91 if not linewrap:
82 self.resultbox.setLineWrapMode(QTextEdit.NoWrap) 92 self.resultbox.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap)
83 93
84 @pyqtSlot(QAbstractButton) 94 @pyqtSlot(QAbstractButton)
85 def on_buttonBox_clicked(self, button): 95 def on_buttonBox_clicked(self, button):
86 """ 96 """
87 Private slot called by a button of the button box clicked. 97 Private slot called by a button of the button box clicked.
88 98
89 @param button button that was clicked (QAbstractButton) 99 @param button button that was clicked
90 """ 100 @type QAbstractButton
91 if button == self.buttonBox.button(QDialogButtonBox.Close): 101 """
102 if button == self.buttonBox.button(
103 QDialogButtonBox.StandardButton.Close
104 ):
92 self.close() 105 self.close()
93 elif button == self.buttonBox.button(QDialogButtonBox.Cancel): 106 elif button == self.buttonBox.button(
107 QDialogButtonBox.StandardButton.Cancel
108 ):
94 self.__finish() 109 self.__finish()
95 elif button == self.buttonBox.button(QDialogButtonBox.Save): 110 elif button == self.buttonBox.button(
111 QDialogButtonBox.StandardButton.Save
112 ):
96 self.__saveData() 113 self.__saveData()
97 114
98 def __finish(self): 115 def __finish(self):
99 """ 116 """
100 Private slot called when the process finished or the user pressed the 117 Private slot called when the process finished or the user pressed the
101 button. 118 button.
102 """ 119 """
103 if ( 120 if (
104 self.proc is not None and 121 self.proc is not None and
105 self.proc.state() != QProcess.NotRunning 122 self.proc.state() != QProcess.ProcessState.NotRunning
106 ): 123 ):
107 self.proc.terminate() 124 self.proc.terminate()
108 QTimer.singleShot(2000, self.proc.kill) 125 QTimer.singleShot(2000, self.proc.kill)
109 self.proc.waitForFinished(3000) 126 self.proc.waitForFinished(3000)
110 127
111 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) 128 self.buttonBox.button(
112 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) 129 QDialogButtonBox.StandardButton.Close).setEnabled(True)
113 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) 130 self.buttonBox.button(
114 self.buttonBox.button(QDialogButtonBox.Save).setEnabled(True) 131 QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
132 self.buttonBox.button(
133 QDialogButtonBox.StandardButton.Close).setDefault(True)
134 self.buttonBox.button(
135 QDialogButtonBox.StandardButton.Save).setEnabled(True)
115 136
116 self.inputGroup.setEnabled(False) 137 self.inputGroup.setEnabled(False)
117 self.inputGroup.hide() 138 self.inputGroup.hide()
118 139
119 self.proc = None 140 self.proc = None
126 147
127 def __procFinished(self, exitCode, exitStatus): 148 def __procFinished(self, exitCode, exitStatus):
128 """ 149 """
129 Private slot connected to the finished signal. 150 Private slot connected to the finished signal.
130 151
131 @param exitCode exit code of the process (integer) 152 @param exitCode exit code of the process
132 @param exitStatus exit status of the process (QProcess.ExitStatus) 153 @type int
133 """ 154 @param exitStatus exit status of the process
134 self.normal = (exitStatus == QProcess.NormalExit) and (exitCode == 0) 155 @type QProcess.ExitStatus
156 """
157 self.normal = (
158 exitStatus == QProcess.ExitStatus.NormalExit and
159 exitCode == 0
160 )
135 self.__finish() 161 self.__finish()
136 162
137 if self.normal and self.msgSuccess: 163 if self.normal and self.msgSuccess:
138 self.resultbox.insertPlainText(self.msgSuccess) 164 self.resultbox.insertPlainText(self.msgSuccess)
139 elif not self.normal and self.msgError: 165 elif not self.normal and self.msgError:
144 def startProcess(self, args, workingDir=None, showCommand=True, 170 def startProcess(self, args, workingDir=None, showCommand=True,
145 mergedOutput=False): 171 mergedOutput=False):
146 """ 172 """
147 Public slot used to start the process. 173 Public slot used to start the process.
148 174
149 @param args list of arguments for the process (list of strings) 175 @param args list of arguments for the process
150 @param workingDir working directory for the process (string) 176 @type list of str
177 @param workingDir working directory for the process
178 @type str
151 @param showCommand flag indicating to show the command executed 179 @param showCommand flag indicating to show the command executed
152 (boolean) 180 @type bool
153 @param mergedOutput flag indicating to merge the output of the process 181 @param mergedOutput flag indicating to merge the output of the process
154 (boolean) 182 @type bool
155 @return flag indicating a successful start of the process (boolean) 183 @return flag indicating a successful start of the process
184 @rtype bool
156 """ 185 """
157 self.errorGroup.hide() 186 self.errorGroup.hide()
158 187
159 self.normal = False 188 self.normal = False
160 189
161 self.proc = QProcess() 190 self.proc = QProcess()
162 if mergedOutput: 191 if mergedOutput:
163 self.proc.setProcessChannelMode(QProcess.MergedChannels) 192 self.proc.setProcessChannelMode(
193 QProcess.ProcessChannelMode.MergedChannels)
164 194
165 if showCommand: 195 if showCommand:
166 self.resultbox.append(' '.join(args)) 196 self.resultbox.append(' '.join(args))
167 self.resultbox.append('') 197 self.resultbox.append('')
168 198
181 self.proc.start(prog, args) 211 self.proc.start(prog, args)
182 procStarted = self.proc.waitForStarted() 212 procStarted = self.proc.waitForStarted()
183 if not procStarted: 213 if not procStarted:
184 self.buttonBox.setFocus() 214 self.buttonBox.setFocus()
185 self.inputGroup.setEnabled(False) 215 self.inputGroup.setEnabled(False)
186 E5MessageBox.critical( 216 EricMessageBox.critical(
187 self, 217 self,
188 self.tr('Process Generation Error'), 218 self.tr('Process Generation Error'),
189 self.tr( 219 self.tr(
190 'The process {0} could not be started. ' 220 'The process {0} could not be started. '
191 'Ensure, that it is in the search path.' 221 'Ensure, that it is in the search path.'
204 mergedOutput=False): 234 mergedOutput=False):
205 """ 235 """
206 Public slot used to start a batch of processes. 236 Public slot used to start a batch of processes.
207 237
208 @param argsLists list of lists of arguments for the processes 238 @param argsLists list of lists of arguments for the processes
209 (list of lists of strings) 239 @type list of list of str
210 @param workingDir working directory for the process (string) 240 @param workingDir working directory for the process
241 @type str
211 @param mergedOutput flag indicating to merge the output of the process 242 @param mergedOutput flag indicating to merge the output of the process
212 (boolean) 243 @type bool
213 @return flag indicating a successful start of the first process 244 @return flag indicating a successful start of the first process
214 (boolean) 245 @rtype bool
215 """ 246 """
216 self.argsLists = argsLists[:] 247 self.argsLists = argsLists[:]
217 self.workingDir = workingDir 248 self.workingDir = workingDir
218 self.mergedOutput = mergedOutput 249 self.mergedOutput = mergedOutput
219 250
229 260
230 def normalExit(self): 261 def normalExit(self):
231 """ 262 """
232 Public method to check for a normal process termination. 263 Public method to check for a normal process termination.
233 264
234 @return flag indicating normal process termination (boolean) 265 @return flag indicating normal process termination
266 @rtype bool
235 """ 267 """
236 return self.normal 268 return self.normal
237 269
238 def normalExitWithoutErrors(self): 270 def normalExitWithoutErrors(self):
239 """ 271 """
240 Public method to check for a normal process termination without 272 Public method to check for a normal process termination without
241 error messages. 273 error messages.
242 274
243 @return flag indicating normal process termination (boolean) 275 @return flag indicating normal process termination
276 @rtype bool
244 """ 277 """
245 return self.normal and self.errors.toPlainText() == "" 278 return self.normal and self.errors.toPlainText() == ""
246 279
247 def __readStdout(self): 280 def __readStdout(self):
248 """ 281 """
273 306
274 def __saveData(self): 307 def __saveData(self):
275 """ 308 """
276 Private slot to save the output to a file. 309 Private slot to save the output to a file.
277 """ 310 """
278 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( 311 fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
279 self, 312 self,
280 self.tr("Select data file"), 313 self.tr("Select data file"),
281 self.workingDir, 314 self.workingDir,
282 self.fileFilters, 315 self.fileFilters,
283 None) 316 None)
293 326
294 try: 327 try:
295 with open(fname, "w", encoding="utf-8") as f: 328 with open(fname, "w", encoding="utf-8") as f:
296 f.write(txt) 329 f.write(txt)
297 except OSError as err: 330 except OSError as err:
298 E5MessageBox.critical( 331 EricMessageBox.critical(
299 self, 332 self,
300 self.tr("Error saving data"), 333 self.tr("Error saving data"),
301 self.tr("""<p>The data could not be written""" 334 self.tr("""<p>The data could not be written"""
302 """ to <b>{0}</b></p><p>Reason: {1}</p>""") 335 """ to <b>{0}</b></p><p>Reason: {1}</p>""")
303 .format(fname, str(err))) 336 .format(fname, str(err)))
304 337
305 def on_passwordCheckBox_toggled(self, isOn): 338 def on_passwordCheckBox_toggled(self, isOn):
306 """ 339 """
307 Private slot to handle the password checkbox toggled. 340 Private slot to handle the password checkbox toggled.
308 341
309 @param isOn flag indicating the status of the check box (boolean) 342 @param isOn flag indicating the status of the check box
343 @type bool
310 """ 344 """
311 if isOn: 345 if isOn:
312 self.input.setEchoMode(QLineEdit.Password) 346 self.input.setEchoMode(QLineEdit.EchoMode.Password)
313 else: 347 else:
314 self.input.setEchoMode(QLineEdit.Normal) 348 self.input.setEchoMode(QLineEdit.EchoMode.Normal)
315 349
316 @pyqtSlot() 350 @pyqtSlot()
317 def on_sendButton_clicked(self): 351 def on_sendButton_clicked(self):
318 """ 352 """
319 Private slot to send the input to the manage.py process. 353 Private slot to send the input to the manage.py process.
342 376
343 def keyPressEvent(self, evt): 377 def keyPressEvent(self, evt):
344 """ 378 """
345 Protected slot to handle a key press event. 379 Protected slot to handle a key press event.
346 380
347 @param evt the key press event (QKeyEvent) 381 @param evt the key press event
382 @type QKeyEvent
348 """ 383 """
349 if self.intercept: 384 if self.intercept:
350 self.intercept = False 385 self.intercept = False
351 evt.accept() 386 evt.accept()
352 return 387 return

eric ide

mercurial