Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6150275
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T19:35:34+00:00 2026-05-23T19:35:34+00:00

So — here’s my jam. I’m SUPER NEW (i.e. days) into Python and have

  • 0

So — here’s my jam. I’m SUPER NEW (i.e. days) into Python and have made some pretty good progress on a GUI for a set of python scripts that I run all the time. It basically builds a database of my music collection. When I run it at the command line, it does a stellar job. I figure it’s a great way to learn python — build a front-end for this thing.

So — the below DOES actually work for me. I hit a problem when the Scan/Update button will stay in a ‘down’ state while the scan gets to work. I learned that, yes, I need to multithread this to get the output from STDOUT to self.LogView in the below. That even works, just not in realtime. I posted about it earlier and got linked to another tutorial on the web, but I am just not getting past this and am getting desperate. Dear Stackflow.com — save me from going insane. If you can make the below work, then I can reverse engineer what you did at least as the tutorials are overly simplified and, yes, I’m in over my head.

The are that is heavy lifting in the below is this:

                    proc = subprocess.Popen([scanCMD],shell=True,stdout=subprocess.PIPE)
                for line in proc.stdout:
                    wx.CallAfter(self.LogWindow.AppendText(line))

In the button def:

def bt_ScanUpdateClick(self, event):

Chow flings a hail mary

#!/usr/bin/python
################################################################################
# myGUI
################################################################################
# THIS WORKS, BUT DOES NOT MULTITHREAD!
################################################################################

import wx
from wxPython.wx import *
import os
import subprocess
import threading

class myGUI(wx.Frame):

    def __init__(self, parent, title):
        super(myGUI, self).__init__(parent, title=title,
            size=(450, 245)) #360 for logwindow (see below)
        panel = wx.Panel(self)
        sizer = wx.GridBagSizer(6, 5)
        self.currentDirectory = os.getcwd()

    # [0] Main Database Text, Entry and Browse Button --------------------------
        label_MainDatabase = wx.StaticText(panel, label="Database:")
        sizer.Add(label_MainDatabase, pos=(0, 0), flag=wx.LEFT|
            wx.ALIGN_CENTER_VERTICAL, border=10)

        self.tc_MainDatabase = wx.TextCtrl(panel)
        sizer.Add(self.tc_MainDatabase, pos=(0, 1), span=(1, 4), flag=wx.TOP|
            wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)

        bt_MainDatabase = wx.Button(panel, label="Browse...")
        sizer.Add(bt_MainDatabase, pos=(0, 5), flag=wx.LEFT|wx.RIGHT|
            wx.ALIGN_CENTER_VERTICAL, border=10)
        bt_MainDatabase.Bind(wx.EVT_BUTTON, self.bt_MainDatabaseClick,
            bt_MainDatabase)
    # --------------------------------------------------------------------------
    # [1] Paths to scan for new Music ------------------------------------------
        self.sb_FoldersToScan = wx.StaticBox(panel, label="Folders to Scan:", size=(200,100))
        folderBoxSizer = wx.StaticBoxSizer(self.sb_FoldersToScan, wx.VERTICAL)
        self.multiText = wx.TextCtrl(panel, -1,"",size=(300, 100), style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.multiText.SetInsertionPoint(0)
        folderBoxSizer.Add(self.multiText, flag=wx.EXPAND)
        sizer.Add(folderBoxSizer, pos=(1, 0), span=(1, 6), flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, border=10)
        bt_FoldersToScanAdd = wx.Button(panel, label="Add")
        bt_FoldersToScanClear = wx.Button(panel, label="Clear")
    # --------------------------------------------------------------------------
    # [2] Buttons to Add Folder, Clear Scan Area -------------------------------
        sizer.Add(bt_FoldersToScanAdd, pos=(2,0), span=(1,2), flag=wx.LEFT|wx.RIGHT|
            wx.ALIGN_CENTER_VERTICAL, border=10)
        bt_FoldersToScanAdd.Bind(wx.EVT_BUTTON, self.bt_FoldersToScanAddClick, bt_FoldersToScanAdd)
        sizer.Add(bt_FoldersToScanClear, pos=(2,5), flag=wx.LEFT|wx.RIGHT|
            wx.ALIGN_CENTER_VERTICAL, border=10)
        bt_FoldersToScanClear.Bind(wx.EVT_BUTTON, self.bt_FoldersToScanClearClick, bt_FoldersToScanClear)
    # --------------------------------------------------------------------------
    # [3] Separator line -------------------------------------------------------
        hl_SepLine1 = wx.StaticLine(panel, 0, (250, 50), (300,1))
        sizer.Add(hl_SepLine1, pos=(3, 0), span=(1, 6), flag=wx.EXPAND, border=10)
    # --------------------------------------------------------------------------
    # [4] Add Scan Options and Scan Button -------------------------------------
        bt_ScanUpdate = wx.Button(panel, label="Scan/Update")
        bt_ScanUpdate.Bind(wx.EVT_BUTTON, self.bt_ScanUpdateClick, bt_ScanUpdate)
        bt_ScanRepair = wx.Button(panel, label="Repair")
        bt_ScanRepair.Bind(wx.EVT_BUTTON, self.bt_ScanRepairClick, bt_ScanRepair)
        self.ck_ScanVerbose = wx.CheckBox(panel, label="Verbose")
        self.ck_ScanLog = wx.CheckBox(panel, label="Log")
        sizer.Add(bt_ScanUpdate, pos=(4,0), span=(1,2), flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, border=10)
        sizer.Add(self.ck_ScanVerbose, pos=(4,2), flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, border=10)
        sizer.Add(self.ck_ScanLog, pos=(4,4), flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, border=10)
        sizer.Add(bt_ScanRepair, pos=(4,5), span=(1,2), flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, border=10)
    # --------------------------------------------------------------------------
    # [5] Separator line ------------------------------------------------------
        hl_SepLine2 = wx.StaticLine(panel, 0, (250, 50), (300,1))
        sizer.Add(hl_SepLine2, pos=(5, 0), span=(1, 6), flag=wx.EXPAND, border=10)
    # --------------------------------------------------------------------------
    # [6] Output/Log Box -------------------------------------------------------
        self.LogWindow = wx.TextCtrl(panel, -1,"",size=(100, 100), style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.LogWindow.SetInsertionPoint(0)
        sizer.Add(self.LogWindow, pos=(6,0), span=(1,6), flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, border=10)

    # DEBUG
        self.multiText.Value = "~/Network/Pictures/Test"

        sizer.AddGrowableCol(2)
        panel.SetSizer(sizer)

        self.Centre()
        self.Show()

    def bt_MainDatabaseClick(self, event):
        # Create a list of filters
        filters = 'All files (*.*)|*.*|Text files (*.db)|*.db'
        dialog = wxFileDialog ( None, message = 'Select Database File...',
            wildcard = filters, style = wxOPEN )

        # Open Dialog Box and get Selection
        if dialog.ShowModal() == wxID_OK:
            selected = dialog.GetFilenames()
            for selection in selected:
                self.tc_MainDatabase.Value = selection
        dialog.Destroy()

    def bt_FoldersToScanAddClick(self, event):
        dialog = wx.DirDialog(self, "Add a Directory...", style=wx.DD_DEFAULT_STYLE)

        if dialog.ShowModal() == wx.ID_OK:
            self.multiText.Value += "%s" % dialog.GetPath() + "\n"
        dialog.Destroy()

    def bt_FoldersToScanClearClick(self, event):
        self.multiText.Value = ""

    def bt_ScanUpdateClick(self, event):
        self.SetSizeWH(450,360)
        thread = threading.Thread()
        thread.setDaemon(True)
        thread.start()

        ## DEBUG
        self.tc_MainDatabase.Value = "test.db"

        if self.tc_MainDatabase.Value == "":
            self.LogWindow.Value += "ERROR:\tNo database name selected!\n"
        else:
            scanCMD = "./scan -d " + self.tc_MainDatabase.Value + " "

            numLines=0
            maxLines=(int(self.multiText.GetNumberOfLines()))

            if self.multiText.GetLineText(numLines) == "":
                self.LogWindow.Value += "ERROR\tNo folder selected to scan!\n"
            else:
                self.LogWindow.Value += "Running Scan...\n\n"
                while (numLines < maxLines):
                    scanCMD += str(self.multiText.GetLineText(numLines)) + " "
                    numLines += 1

                self.LogWindow.Value += scanCMD

                proc = subprocess.Popen([scanCMD],shell=True,stdout=subprocess.PIPE)
                for line in proc.stdout:
                    wx.CallAfter(self.LogWindow.AppendText(line))

#                p = subprocess.Popen([scanCMD],shell=True,stdout=subprocess.PIPE)
#                self.LogWindow.Value += p.stdout.readline()

    def bt_ScanRepairClick(self, event):
        print "Repair clicked"

if __name__ == '__main__':
    app = wx.App()
    myGUI(None, title="myGUI")

    app.MainLoop()
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T19:35:35+00:00Added an answer on May 23, 2026 at 7:35 pm

    I have never needed to set my thread to a daemon before. In fact, I have only ever subclassed Thread. I’m not a threading expert, so I recommend looking at http://wiki.wxpython.org/LongRunningTasks and trying one of the methods there or use the methodology I used here: http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/ I’ve used the latter several times with no problems. Otherwise, you should cross-post to the official wxPython user’s group, which has some very knowledgeable people there that I’m sure could help you.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

We have different types of hyphens/dashes (in some text) populated in db. Before comparing
I basically have the classic many to many model. A user, an award, and
So to start, I have an array of XML files. These files need to
I'm using some of Firefox's specially-defined values for cursor, in particular -moz-zoom-in -moz-zoom-out -moz-grab
I'm trying to write a web application using the new offline capabilities of HTML5.
&mdash; or &#8212; Is there a difference between these? Is one better-supported than the
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I recently ran against a very interesting site that expresses a very interesting idea
My app uses a WebRequest at certain points to get pages from itself. This
By fixed vector I mean a static list of values, like 1 through 24.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.