I have made a library of open-source PyQt custom widgets - one of which is a logger class (XLoggerWidget) and another of which is a full Python interpreter (XConsoleEdit). It does what you're looking for.
You can get it here if you want: http://dev.projexsoftware.com/projects/projexui
The part you're looking for is in the XConsoleEdit (projexui.widgets.xconsoleedit), but the general gist of it is:
import logging
import sys
from PyQt4.QtCore import QObject,
pyqtSignal
from PyQt4.QtGui import QDialog,
QVBoxLayout,
QPushButton,
QTextBrowser,
QApplication
logger = logging.getLogger(__name__)
class XStream(QObject):
_stdout = None
_stderr = None
messageWritten = pyqtSignal(str)
def flush( self ):
pass
def fileno( self ):
return -1
def write( self, msg ):
if ( not self.signalsBlocked() ):
self.messageWritten.emit(unicode(msg))
@staticmethod
def stdout():
if ( not XStream._stdout ):
XStream._stdout = XStream()
sys.stdout = XStream._stdout
return XStream._stdout
@staticmethod
def stderr():
if ( not XStream._stderr ):
XStream._stderr = XStream()
sys.stderr = XStream._stderr
return XStream._stderr
class MyDialog(QDialog):
def __init__( self, parent = None ):
super(MyDialog, self).__init__(parent)
# setup the ui
self._console = QTextBrowser(self)
self._button = QPushButton(self)
self._button.setText('Test Me')
# create the layout
layout = QVBoxLayout()
layout.addWidget(self._console)
layout.addWidget(self._button)
self.setLayout(layout)
# create connections
XStream.stdout().messageWritten.connect( self._console.insertPlainText )
XStream.stderr().messageWritten.connect( self._console.insertPlainText )
self._button.clicked.connect(self.test)
def test( self ):
# print some stuff
print 'testing'
print 'testing2'
# log some stuff
logger.debug('Testing debug')
logger.info('Testing info')
logger.warning('Testing warning')
logger.error('Testing error')
# error out something
print blah
if ( __name__ == '__main__' ):
logging.basicConfig()
app = None
if ( not QApplication.instance() ):
app = QApplication([])
dlg = MyDialog()
dlg.show()
if ( app ):
app.exec_()
This is a simplified version of whats in the XConsoleEdit, but its the general idea and should still work for what you're going for if you don't want to download the code.
In this example tho, you'll notice that only the print and error logs are routed through to the edit. If you want to connect the Python logging system to the edit, you'll need something a little more complex where you define a logging.Handler and link it to your widget.
That code would be found in projexui.widgets.xloggerwidget
Its a bit longer and more complex, so I'm not going to load it up here...but if you have any questions about it, let me know.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…