Plugins/UiExtensionPlugins/PipInterface/PipDialog.py

changeset 6011
e6af0dcfbb35
child 6048
82ad8ec9548c
equal deleted inserted replaced
6010:7ef7d47a0ad5 6011:e6af0dcfbb35
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2015 - 2017 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog showing the output of a pip command.
8 """
9
10 from __future__ import unicode_literals
11 try:
12 str = unicode # __IGNORE_EXCEPTION__
13 except NameError:
14 pass
15
16 from PyQt5.QtCore import pyqtSlot, Qt, QCoreApplication, QTimer, \
17 QProcess
18 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton
19
20 from E5Gui import E5MessageBox
21
22 from .Ui_PipDialog import Ui_PipDialog
23
24 import Preferences
25
26
27 class PipDialog(QDialog, Ui_PipDialog):
28 """
29 Class implementing a dialog showing the output of a pip command.
30 """
31 def __init__(self, text, parent=None):
32 """
33 Constructor
34
35 @param text text to be shown by the label (string)
36 @param parent reference to the parent widget (QWidget)
37 """
38 super(PipDialog, self).__init__(parent)
39 self.setupUi(self)
40
41 self.proc = None
42 self.__processQueue = []
43 self.__ioEncoding = Preferences.getSystem("IOEncoding")
44
45 self.outputGroup.setTitle(text)
46
47 self.show()
48 QCoreApplication.processEvents()
49
50 def closeEvent(self, e):
51 """
52 Protected slot implementing a close event handler.
53
54 @param e close event (QCloseEvent)
55 """
56 self.__processQueue = []
57
58 if self.proc is not None and \
59 self.proc.state() != QProcess.NotRunning:
60 self.proc.terminate()
61 QTimer.singleShot(2000, self.proc.kill)
62 self.proc.waitForFinished(3000)
63
64 self.proc = None
65
66 e.accept()
67
68 def __finish(self):
69 """
70 Private slot called when the process finished or the user pressed
71 the button.
72 """
73 if self.proc is not None and \
74 self.proc.state() != QProcess.NotRunning:
75 self.proc.terminate()
76 QTimer.singleShot(2000, self.proc.kill)
77 self.proc.waitForFinished(3000)
78
79 self.proc = None
80
81 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
82 self.buttonBox.button(QDialogButtonBox.Close).setFocus(
83 Qt.OtherFocusReason)
84
85 if self.__processQueue:
86 cmd, args = self.__processQueue.pop(0)
87 self.__addOutput("\n\n")
88 self.startProcess(cmd, args)
89
90 @pyqtSlot(QAbstractButton)
91 def on_buttonBox_clicked(self, button):
92 """
93 Private slot called by a button of the button box clicked.
94
95 @param button button that was clicked (QAbstractButton)
96 """
97 if button == self.buttonBox.button(QDialogButtonBox.Close):
98 self.close()
99
100 def __procFinished(self, exitCode, exitStatus):
101 """
102 Private slot connected to the finished signal.
103
104 @param exitCode exit code of the process (integer)
105 @param exitStatus exit status of the process (QProcess.ExitStatus)
106 """
107 self.__finish()
108
109 def startProcess(self, cmd, args, showArgs=True):
110 """
111 Public slot used to start the process.
112
113 @param cmd name of the pip executable to be used (string)
114 @param args list of arguments for the process (list of strings)
115 @keyparam showArgs flag indicating to show the arguments (boolean)
116 @return flag indicating a successful start of the process
117 """
118 if len(self.errors.toPlainText()) == 0:
119 self.errorGroup.hide()
120
121 if showArgs:
122 self.resultbox.append(cmd + ' ' + ' '.join(args))
123 self.resultbox.append('')
124
125 self.proc = QProcess()
126 self.proc.finished.connect(self.__procFinished)
127 self.proc.readyReadStandardOutput.connect(self.__readStdout)
128 self.proc.readyReadStandardError.connect(self.__readStderr)
129 self.proc.start(cmd, args)
130 procStarted = self.proc.waitForStarted(5000)
131 if not procStarted:
132 self.buttonBox.setFocus()
133 E5MessageBox.critical(
134 self,
135 self.tr('Process Generation Error'),
136 self.tr(
137 'The process {0} could not be started.'
138 ).format(cmd))
139 return procStarted
140
141 def startProcesses(self, processParams):
142 """
143 Public method to issue a list of commands to be executed.
144
145 @param processParams list of tuples containing the command
146 and arguments
147 @type list of tuples of str and list of str
148 @return flag indicating a successful start of the first process
149 @rtype bool
150 """
151 if len(processParams) > 1:
152 for cmd, args in processParams[1:]:
153 self.__processQueue.append((cmd, args[:]))
154 cmd, args = processParams[0]
155 return self.startProcess(cmd, args)
156
157 def __readStdout(self):
158 """
159 Private slot to handle the readyReadStandardOutput signal.
160
161 It reads the output of the process, formats it and inserts it into
162 the contents pane.
163 """
164 if self.proc is not None:
165 txt = str(self.proc.readAllStandardOutput(),
166 self.__ioEncoding, 'replace')
167 self.__addOutput(txt)
168
169 def __addOutput(self, txt):
170 """
171 Private method to add some text to the output pane.
172
173 @param txt text to be added
174 @type str
175 """
176 self.resultbox.insertPlainText(txt)
177 self.resultbox.ensureCursorVisible()
178 QCoreApplication.processEvents()
179
180 def __readStderr(self):
181 """
182 Private slot to handle the readyReadStandardError signal.
183
184 It reads the error output of the process and inserts it into the
185 error pane.
186 """
187 if self.proc is not None:
188 s = str(self.proc.readAllStandardError(),
189 self.__ioEncoding, 'replace')
190 self.errorGroup.show()
191 self.errors.insertPlainText(s)
192 self.errors.ensureCursorVisible()
193
194 QCoreApplication.processEvents()

eric ide

mercurial