Creek Barbara
Creek Barbara

Reputation: 647

wxPython: Create a log system

I have an application that calls another script when clicking on a button. On that script, I have some prints that I would like to display on a wx.TextCtrl widget on the application but I have no clue where to start.

This is an example of the script called:

#export.py

def exportData():
    #some code
    #Some prints that I would like to display on the application

And here is how I call the script from the application:

def loadData(self, event):
    from export import exportData
    exportData()

I have some questions:

  1. I assume that print won't work as a log, and I have to use some kind of logging system. Is that correct? I've tried to use log.write but I keep getting "log not defined error".
  2. Maybe calling exportData() directly from def loadData isn't the best way to proceed. If it's the case, what is the correct way?
  3. Finally, How can I display the prints/logs into the wx.TextCtrl widget of the application?

Don't hesitate if you need more information. Thank you in advance for your help.

EDIT

Here is a minimalist working example code of what I'm trying to do. Printing "This is my log" in the main.py TextCtrl.

# main.py
import wx, sys
import export

class Test(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, "Frame aka Window", size=(300, 200))
        panel = wx.Panel(self)
        log = wx.TextCtrl(panel, style=wx.TE_MULTILINE|wx.TE_READONLY)

        button = wx.Button(panel, label="Export", pos=(80, 80), size=(120, 30))

        self.Bind(wx.EVT_BUTTON, self.export, button)

        mySizer = wx.BoxSizer(wx.VERTICAL)
        mySizer.Add(button, 0, wx.ALL | wx.ALIGN_CENTER, 5)
        mySizer.Add(log, 0, wx.ALL | wx.ALIGN_CENTER, 5)

        panel.SetSizer(mySizer)


    def export(self, event):
        from export import exportData
        exportData()


if __name__ == '__main__':
    app = wx.App()
    frame = Test(parent=None, id=1)
    frame.Show()
    app.MainLoop()

and the export file:

#export.py

def exportData():
    print("This is my log")

Upvotes: 1

Views: 760

Answers (2)

Rolf of Saxony
Rolf of Saxony

Reputation: 22443

Firstly, congratulations on engineering the following statement import export, it makes me smile each time I see it.
Are you attempting something like this?

enter image description here

Here is your amended code to do that:

# main.py
import wx, sys
from export import exportData

class Test(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, "Frame aka Window", size=(300, 200))
        panel = wx.Panel(self)
        self.log = wx.TextCtrl(panel, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(180,100))
        button = wx.Button(panel, label="Export")
        self.Bind(wx.EVT_BUTTON, self.export, button)
        mySizer = wx.BoxSizer(wx.VERTICAL)
        mySizer.Add(button, 0, wx.ALL | wx.ALIGN_CENTER, 5)
        mySizer.Add(self.log, 0, wx.ALL | wx.ALIGN_CENTER, 5)
        panel.SetSizer(mySizer)

    def export(self, event):
        exportData(parent=self)

if __name__ == '__main__':
    app = wx.App()
    frame = Test(parent=None, id=1)
    frame.Show()
    app.MainLoop()

and the export.py

import time
import wx

def exportData(parent=None):
    if not parent:
        return
    log = []
    print("This is my log")
    parent.log.write("This is my log\n")
    #solely for the purpose of illustrating updates in real time use sleep between updates
    # and yield to the gui main loop
    # in real time operation remove the sleep commands
    wx.Yield()
    time.sleep(1)
    print("Log line 2")
    parent.log.write("Log line 2\n")
    wx.Yield()
    time.sleep(1)
    print("Log line 3")
    parent.log.write("Log line 3\n")
    wx.Yield()
    time.sleep(1)
    print("Export data has concluded")

All that is happening here is we pass the parent to the function, which allows the updates to occur in real-time. The call to Yield passes control momentarily back to the wx.App.MainLoop for the update to be seen occurring, otherwise, although the update occurred, the result isn't seen, until the MainLoop takes back control.

Upvotes: 3

K-Doe
K-Doe

Reputation: 559

You could create a "Log" as an TextCtrl.

self.log = wx.TextCtrl(Panel, style=wx.TE_MULTILINE|wx.TE_READONLY)

If you want to add something your could write it like this:

self.log.AppendText('Your String here')

To clear it you do it like this:

self.log.Clear()

To be more detailed we need to see more of your code. But maybe this will help you already.

Also i would import on top of your Module not inside a function.

from export import exportData

def loadData(self, event):        
        exportData(yourLogData)

I dont know where the information for you log are coming from but i would assume you need to pass it to exportData like this:

[...]
self.log = wx.TextCtrl(Panel, style=wx.TE_MULTILINE|wx.TE_READONLY)
[...]
def exportData(self, yourLogData):
    #some code
    #Some prints that I would like to display on the application
    self.log.AppendText(yourLogData)

Upvotes: 1

Related Questions