0

I was trying to show both stdout and stderr in my PyQt (pyqtgraph) application. If I follow the Ferdinand Beyer's answer to this question, I am able to do so.

However, when I try to append a timestamp before the stdout by changing the text inside the write() function

new_text = '{}> {}'.format(time.strftime('%X'), old_text)

I get the timestamp attached before and after the stdout message. I am confused about this behavior and fail to figure out why it happens and how to prevent it.

UPDATE: my code directly:

from pyqtgraph.Qt import QtGui,QtCore
from pyqtgraph.dockarea import DockArea,Dock
import pyqtgraph as pg
import sys
import time

app = QtGui.QApplication([])
win = QtGui.QMainWindow()
win.resize(300,300)
area = DockArea()
win.setCentralWidget(area)
d1 = Dock("cmd output", size=(300,300))
area.addDock(d1)

w1 = pg.LayoutWidget()
gui_cmd_bw = QtGui.QTextBrowser()
w1.addWidget(gui_cmd_bw,0,0)

d1.addWidget(w1)

class EmittingStream(QtCore.QObject):

    textWritten = QtCore.pyqtSignal(str)

    def write(self, text):
        self.textWritten.emit(str(text))        

def normalOutputWritten(text):
    """Append text to the QTextEdit."""
    # this works without problems.
    #gui_cmd_bw.insertPlainText(text)
    timestamp = '{}> '.format(time.strftime('%X'))
    # this adds timestamp before and after the stdout
    gui_cmd_bw.insertPlainText(timestamp+text)
    # this produces similar result
    #gui_cmd_bw.append(timestamp+text)

# cmd output to application browser
sys.stdout = EmittingStream(textWritten=normalOutputWritten)
sys.stderr = EmittingStream(textWritten=normalOutputWritten)

win.show()
if __name__ == '__main__':    
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        print('stdout text')        
        QtGui.QApplication.instance().exec_()

Final output looks like this:

14:15:16> stdout text
14:15:16> 
queezz
  • 1,832
  • 2
  • 20
  • 26
  • 1
    you could indicate in which part we use new_text, perhaps your complete example would help to understand the problem, otherwise it will be difficult – eyllanesc Apr 11 '18 at 05:03
  • Thank you. I added my example to the question. – queezz Apr 11 '18 at 05:23
  • 2
    The problem is that `print` writes each argument (including `sep` and `end`) *separately*. So `print('1', '2', '3')` will call `sys.stdout.write()` ***six*** times in total. – ekhumoro Apr 11 '18 at 21:43

1 Answers1

0

I found a fast workaround to my problem, which is good enough for me.

Since print() function calls sys.stdout.write() twice for each output, I added condition to check if this output is not empty.

def normalOutputWritten(text):
    """Append text to the QTextEdit."""       
    timestamp = '{}> '.format(time.strftime('%X'))    

   if len(text)>1:
        text = timestamp+text

   gui_cmd_bw.insertPlainText(text) 

This removes the second timestamp. Of course time stamp will be missing from one symbol outputs.

queezz
  • 1,832
  • 2
  • 20
  • 26