これは私のジャムです。私はPythonにSUPER NEW(すなわちdays)を使用しています。常に実行している一連のpythonスクリプトのGUI上でかなり良い進歩を遂げました。基本的に私の音楽コレクションのデータベースを構築します。私はコマンドラインでそれを実行すると、それは恒星の仕事を行います。私はそれがPythonを学ぶのに最適な方法だと考えています - このことのフロントエンドを構築してください。wxPython:マルチスレッドヘルプ
したがって、以下は実際に私のために働いています。私はスキャンが動作するようになっている間、スキャン/アップデートボタンが「ダウン」状態のままになるときに問題に遭遇しました。私は、はい、私は、STDOUTからのself.LogViewに出力を得るために、これをマルチスレッドする必要があることを学んだ。それも機能します。リアルタイムではありません。私はそれについて以前に投稿し、ウェブ上の別のチュートリアルにリンクしていましたが、これを過ぎていないだけで、必死になっています。親愛なるStackflow.com - 私を狂人から救ってください。以下の作業を行うことができれば、チュートリアルが過度に簡素化され、少なくとも私の頭の中に入っているので、少なくともあなたが行ったことをリバースエンジニアリングすることができます。 DEFボタンで
proc = subprocess.Popen([scanCMD],shell=True,stdout=subprocess.PIPE)
for line in proc.stdout:
wx.CallAfter(self.LogWindow.AppendText(line))
:ザ・はそれは以下に力仕事である
はこれです
def bt_ScanUpdateClick(self, event):
チョウは私が
#!/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()
私はそれが働いていると思う - ありがとうマイク。 :)今は、スレッドでうまくいくようにSTDOUTを取得することはできませんが、スレッド*が動作しているようです。 – chow