⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 browse.py

📁 Urwid is a Python library for making text console applications. It has many features including fluid
💻 PY
📖 第 1 页 / 共 2 页
字号:
#!/usr/bin/python## Urwid example lazy directory browser / tree view#    Copyright (C) 2004-2007  Ian Ward##    This library is free software; you can redistribute it and/or#    modify it under the terms of the GNU Lesser General Public#    License as published by the Free Software Foundation; either#    version 2.1 of the License, or (at your option) any later version.##    This library is distributed in the hope that it will be useful,#    but WITHOUT ANY WARRANTY; without even the implied warranty of#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU#    Lesser General Public License for more details.##    You should have received a copy of the GNU Lesser General Public#    License along with this library; if not, write to the Free Software#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA## Urwid web site: http://excess.org/urwid/"""Urwid example lazy directory browser / tree viewFeatures:- custom selectable widgets for files and directories- custom message widgets to identify access errors and empty directories- custom list walker for displaying widgets in a tree fashion- outputs a quoted list of files and directories "selected" on exit"""import urwidimport urwid.raw_displayimport osclass TreeWidget(urwid.WidgetWrap):	"""A widget representing something in the file tree."""	def __init__(self, dir, name, index, display):		self.dir = dir		self.name = name		self.index = index		parent, _ign = os.path.split(dir)		# we're at the top if parent is same as dir		if dir == parent:			self.depth = 0		else:		 	self.depth = dir.count(dir_sep())		widget = urwid.Text(["  "*self.depth, display])		self.widget = widget		w = urwid.AttrWrap(widget, None)		self.__super.__init__(w)		self.selected = False		self.update_w()				def selectable(self):		return True		def keypress(self, (maxcol,), key):		"""Toggle selected on space, ignore other keys."""		if key == " ":			self.selected = not self.selected			self.update_w()		else:			return key	def update_w(self):		"""Update the attributes of self.widget based on self.selected.		"""		if self.selected:			self.w.attr = 'selected'			self.w.focus_attr = 'selected focus'		else:			self.w.attr = 'body'			self.w.focus_attr = 'focus'			def first_child(self):		"""Default to have no children."""		return None		def last_child(self):		"""Default to have no children."""		return None		def next_inorder(self):		"""Return the next TreeWidget depth first from this one."""				child = self.first_child()		if child: 			return child		else:			dir = get_directory(self.dir)			return dir.next_inorder_from(self.index)		def prev_inorder(self):		"""Return the previous TreeWidget depth first from this one."""				dir = get_directory(self.dir)		return dir.prev_inorder_from(self.index)class EmptyWidget(TreeWidget):	"""A marker for expanded directories with no contents."""	def __init__(self, dir, name, index):		self.__super.__init__(dir, name, index, 			('flag',"(empty directory)"))		def selectable(self):		return False	class ErrorWidget(TreeWidget):	"""A marker for errors reading directories."""	def __init__(self, dir, name, index):		self.__super.__init__(dir, name, index, 			('error',"(error/permission denied)"))		def selectable(self):		return Falseclass FileWidget(TreeWidget):	"""Widget for a simple file (or link, device node, etc)."""		def __init__(self, dir, name, index):		self.__super.__init__(dir, name, index, name)class DirectoryWidget(TreeWidget):	"""Widget for a directory."""		def __init__(self, dir, name, index ):		self.__super.__init__(dir, name, index, "")				# check if this directory starts expanded		self.expanded = starts_expanded( os.path.join(dir,name) )				self.update_widget()		def update_widget(self):		"""Update display widget text."""				if self.expanded:			mark = "+"		else:			mark = "-"		self.widget.set_text( ["  "*(self.depth),			('dirmark', mark), " ", self.name] )	def keypress(self, (maxcol,), key ):		"""Handle expand & collapse requests."""				if key == "+":			self.expanded = True			self.update_widget()		elif key == "-":			self.expanded = False			self.update_widget()		else:			return self.__super.keypress((maxcol,), key)		def mouse_event(self, (maxcol,), event, button, col, row, focus):		if event != 'mouse press' or button!=1:			return False		if row == 0 and col == 2*self.depth:			self.expanded = not self.expanded			self.update_widget()			return True				return False		def first_child(self):		"""Return first child if expanded."""				if not self.expanded: 			return None		full_dir = os.path.join(self.dir, self.name)		dir = get_directory( full_dir )		return dir.get_first()		def last_child(self):		"""Return last child if expanded."""				if not self.expanded:			return None		full_dir = os.path.join(self.dir, self.name)		dir = get_directory( full_dir )		widget = dir.get_last()		sub = widget.last_child()		if sub is not None:			return sub		return widget				class Directory:	"""Store sorted directory contents and cache TreeWidget objects."""		def __init__(self, path):		self.path = path		self.widgets = {}		dirs = []		files = []		try:			# separate dirs and files			for a in os.listdir(path):				if os.path.isdir(os.path.join(path,a)):					dirs.append( a )				else:					files.append( a )		except OSError, e:			self.widgets[None] = ErrorWidget( self.path, None, 0 )		# sort dirs and files		dirs.sort(sensible_cmp)		files.sort(sensible_cmp)		# store where the first file starts		self.dir_count = len(dirs)		# collect dirs and files together again		self.items = dirs + files		# if no items, put a dummy None item in the list		if not self.items:			self.items = [None]	def get_widget(self, name):		"""Return the widget for a given file.  Create if necessary."""				if self.widgets.has_key( name ):			return self.widgets[name]				# determine the correct TreeWidget type (constructor)		index = self.items.index( name )		if name is None:			constructor = EmptyWidget		elif index < self.dir_count:			constructor = DirectoryWidget		else:			constructor = FileWidget		widget = constructor( self.path, name, index )				self.widgets[name] = widget		return widget			def next_inorder_from(self, index):		"""Return the TreeWidget following index depth first."""			index += 1		# try to get the next item at same level		if index < len(self.items):			return self.get_widget(self.items[index])					# need to go up a level		parent, myname = os.path.split(self.path)		# give up if we can't go higher		if parent == self.path: return None		# find my location in parent, and return next inorder		pdir = get_directory( parent )		mywidget = pdir.get_widget( myname )		return pdir.next_inorder_from( mywidget.index )			def prev_inorder_from(self, index):		"""Return the TreeWidget preceeding index depth first."""				index -= 1		if index >= 0:			widget = self.get_widget(self.items[index])			widget_child = widget.last_child()			if widget_child: 				return widget_child			else:				return widget		# need to go up a level		parent, myname = os.path.split(self.path)		# give up if we can't go higher		if parent == self.path: return None		# find myself in parent, and return		pdir = get_directory( parent )		return pdir.get_widget( myname )	def get_first(self):		"""Return the first TreeWidget in the directory."""				return self.get_widget(self.items[0])		def get_last(self):		"""Return the last TreeWIdget in the directory."""				return self.get_widget(self.items[-1])		class DirectoryWalker(urwid.ListWalker):	"""ListWalker-compatible class for browsing directories.		positions used are directory,filename tuples."""		def __init__(self, start_from ):		parent = start_from		dir = get_directory(parent)		widget = dir.get_first()		self.focus = parent, widget.name	def get_focus(self):		parent, name = self.focus		dir = get_directory( parent )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -