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

📄 widget.py

📁 Urwid is a Python library for making text console applications. It has many features including fluid
💻 PY
📖 第 1 页 / 共 5 页
字号:
		self.caption, self.attrib = decompose_tagmarkup(caption)		self._invalidate()		def set_edit_pos(self, pos):		"""Set the cursor position with a self.edit_text offset."""		assert pos >= 0 and pos <= len(self.edit_text), "out of range"		self.highlight = None		self.pref_col_maxcol = None, None		self.edit_pos = pos		self._invalidate()		def set_edit_text(self, text):		"""Set the edit text for this widget."""		self.highlight = None		self.edit_text = text		if self.edit_pos > len(text):			self.edit_pos = len(text)		self._invalidate()	def get_edit_text(self):		"""Return the edit text for this widget."""		return self.edit_text	def insert_text(self, text):		"""Insert text at the cursor position and update cursor."""		p = self.edit_pos		self.set_edit_text( self.edit_text[:p] + text + 			self.edit_text[p:] )		self.set_edit_pos( self.edit_pos + len(text))		def keypress(self,(maxcol,),key):		"""Handle editing keystrokes, return others."""		p = self.edit_pos		if self.valid_char(key):			self._delete_highlighted()			if type(key) == type(u""):				key = key.encode("utf-8")			self.insert_text( key )					elif key=="tab" and self.allow_tab:			self._delete_highlighted() 			key = " "*(8-(self.edit_pos%8))			self.insert_text( key )		elif key=="enter" and self.multiline:			self._delete_highlighted() 			key = "\n"			self.insert_text( key )		elif key=="left":			if p==0: return key			p = move_prev_char(self.edit_text,0,p)			self.set_edit_pos(p)				elif key=="right":			if p >= len(self.edit_text): return key			p = move_next_char(self.edit_text,p,len(self.edit_text))			self.set_edit_pos(p)				elif key in ("up","down"):			self.highlight = None						x,y = self.get_cursor_coords((maxcol,))			pref_col = self.get_pref_col((maxcol,))			assert pref_col is not None			#if pref_col is None: 			#	pref_col = x			if key == "up": y -= 1			else:		y += 1			if not self.move_cursor_to_coords((maxcol,),pref_col,y):				return key				elif key=="backspace":			self._delete_highlighted()			self.pref_col_maxcol = None, None			if p == 0: return key			p = move_prev_char(self.edit_text,0,p)			self.set_edit_text( self.edit_text[:p] + 				self.edit_text[self.edit_pos:] )			self.set_edit_pos( p )		elif key=="delete":			self._delete_highlighted()			self.pref_col_maxcol = None, None			if p >= len(self.edit_text):				return key			p = move_next_char(self.edit_text,p,len(self.edit_text))			self.set_edit_text( self.edit_text[:self.edit_pos] + 				self.edit_text[p:] )				elif key in ("home", "end"):			self.highlight = None			self.pref_col_maxcol = None, None						x,y = self.get_cursor_coords((maxcol,))						if key == "home":				self.move_cursor_to_coords((maxcol,),'left',y)			else:				self.move_cursor_to_coords((maxcol,),'right',y)			return								else:			# key wasn't handled			return key	def move_cursor_to_coords(self, (maxcol,), x, y):		"""Set the cursor position with (x,y) coordinates.		Returns True if move succeeded, False otherwise.		"""		trans = self.get_line_translation(maxcol)		top_x, top_y = self.position_coords(maxcol, 0)		if y < top_y or y >= len(trans):			return False		pos = calc_pos( self.get_text()[0], trans, x, y )		e_pos = pos - len(self.caption)		if e_pos < 0: e_pos = 0		if e_pos > len(self.edit_text): e_pos = len(self.edit_text)		self.edit_pos = e_pos		self.pref_col_maxcol = x, maxcol		self._invalidate()		return True	def mouse_event(self, (maxcol,), event, button, x, y, focus):		"""		Move the cursor to the location clicked for button 1.		"""		if button==1:			return self.move_cursor_to_coords( (maxcol,), x, y )	def _delete_highlighted(self):		"""		Delete all highlighted text and update cursor position, if any		text is highlighted.		"""		if not self.highlight: return		start, stop = self.highlight		btext, etext = self.edit_text[:start], self.edit_text[stop:]		self.set_edit_text( btext + etext )		self.edit_pos = start		self.highlight = None					def render(self,(maxcol,), focus=False):		""" 		Render edit widget and return canvas.  Include cursor when in		focus.		"""		self._shift_view_to_cursor = not not focus # force bool				canv = Text.render(self,(maxcol,))		if focus:			canv = CompositeCanvas(canv)			canv.cursor = self.get_cursor_coords((maxcol,))		# .. will need to FIXME if I want highlight to work again		#if self.highlight:		#	hstart, hstop = self.highlight_coords()		#	d.coords['highlight'] = [ hstart, hstop ]		return canv		def get_line_translation(self, maxcol, ta=None ):		trans = Text.get_line_translation(self, maxcol, ta)		if not self._shift_view_to_cursor: 			return trans				text, ignore = self.get_text()		x,y = calc_coords( text, trans, 			self.edit_pos + len(self.caption) )		if x < 0:			return ( trans[:y]				+ [shift_line(trans[y],-x)]				+ trans[y+1:] )		elif x >= maxcol:			return ( trans[:y] 				+ [shift_line(trans[y],-(x-maxcol+1))]				+ trans[y+1:] )		return trans				def get_cursor_coords(self,(maxcol,)):		"""Return the (x,y) coordinates of cursor within widget."""		self._shift_view_to_cursor = True		return self.position_coords(maxcol,self.edit_pos)			def position_coords(self,maxcol,pos):		"""		Return (x,y) coordinates for an offset into self.edit_text.		"""				p = pos + len(self.caption)		trans = self.get_line_translation(maxcol)		x,y = calc_coords(self.get_text()[0], trans,p)		return x,y		class IntEdit(Edit):	"""Edit widget for integer values"""	def valid_char(self, ch):		"""Return true for decimal digits."""		return len(ch)==1 and ord(ch)>=ord('0') and ord(ch)<=ord('9')		def __init__(self,caption="",default=None):		"""		caption -- caption markup		default -- default edit value		"""		if default is not None: val = str(default)		else: val = ""		self.__super.__init__(caption,val)	def keypress(self,(maxcol,),key):		"""Handle editing keystrokes.  Return others."""	        if key in list("0123456789"):			# trim leading zeros	                while self.edit_pos > 0 and self.edit_text[:1] == "0":	                        self.set_edit_pos( self.edit_pos - 1)	                        self.set_edit_text(self.edit_text[1:])	        unhandled = Edit.keypress(self,(maxcol,),key)		return unhandled	def value(self):		"""Return the numeric value of self.edit_text."""		if self.edit_text:			return long(self.edit_text)		else:			return 0class WidgetWrap(Widget):	no_cache = ["rows"]	def __init__(self, w):		"""		w -- widget to wrap, stored as self.w		This object will pass the functions defined in Widget interface		definition to self.w.		"""		self._w = w	def get_w(self):		return self._w	def set_w(self, w):		self._w = w		self._invalidate()	w = property(get_w, set_w)		def render(self, size, focus=False):		"""Render self.w."""		canv = self.w.render(size, focus=focus)		return CompositeCanvas(canv)	def selectable(self):		return self.w.selectable()	def __getattr__(self,name):		"""Call self.w if name is in Widget interface definition."""		if name in ['get_cursor_coords','get_pref_col','keypress',			'move_cursor_to_coords','rows','mouse_event',]:			return getattr(self._w, name)		raise AttributeError, nameclass SelectableIcon(Text):	def selectable(self):		return True		def render(self, (maxcol,), focus=False):		c = Text.render(self, (maxcol,), focus )		if focus:			c = CompositeCanvas(c)			c.cursor = self.get_cursor_coords((maxcol,))		return c		def get_cursor_coords(self, (maxcol,)):		if maxcol>1:			return (1,0)	def keypress(self, (maxcol,), key):		return keyclass CheckBox(WidgetWrap):	states = { 		True: SelectableIcon("[X]"),		False: SelectableIcon("[ ]"),		'mixed': SelectableIcon("[#]") }	reserve_columns = 4	def selectable(self): return True		def __init__(self, label, state=False, has_mixed=False,		     on_state_change=None, user_data=None):		"""		label -- markup for check box label		state -- False, True or "mixed"		has_mixed -- True if "mixed" is a state to cycle through		on_state_change -- callback function for state changes		                   on_state_change( check box, new state,				                    user_data=None)		user_data -- additional param for on_press callback,		             ommited if None for compatibility reasons		"""		self.__super.__init__(None) # self.w set by set_state below		self.label = Text("")		self.has_mixed = has_mixed		self.state = None		self.on_state_change = on_state_change		self.user_data = user_data		self.set_label(label)		self.set_state(state)		def set_label(self, label):		"""Change the check box label."""		self.label.set_text(label)		self._invalidate()		def get_label(self):		"""Return label text."""		text, attr = self.label.get_text()		return text		def set_state(self, state, do_callback=True):		"""		Call on_state_change if do_callback is True,		then change the check box state.		"""		if (do_callback and self.state is not None and 			self.on_state_change):			if self.user_data is None:				self.on_state_change(self, state)			else:				self.on_state_change(self, state,						     self.user_data)		self.state = state		self.w = Columns( [			('fixed', self.reserve_columns, self.states[state] ),			self.label ] )		self.w.focus_col = 0		self._invalidate()			def get_state(self):		"""Return the state of the checkbox."""		return self.state			def keypress(self, (maxcol,), key):		"""Toggle state on space or enter."""		if key not in (' ','enter'):			return key				self.toggle_state()			def toggle_state(self):		"""Cycle to the next valid state."""		if self.state == False:			self.set_state(True)		elif self.state == True:			if self.has_mixed:				self.set_state('mixed')			else:				self.set_state(False)		elif self.state == 'mixed':			self.set_state(False)		self._invalidate()	def mouse_event(self, (maxcol,), event, button, x, y, focus):		"""Toggle state on button 1 press."""		if button != 1 or not is_mouse_press(event):			return False		self.toggle_state()		return True			class RadioButton(WidgetWrap):	states = { 		True: SelectableIcon("(X)"),		False: SelectableIcon("( )"),		'mixed': SelectableIcon("(#)") }	reserve_columns = 4	def selectable(self): return True		def __init__(self, group, label, state="first True",		     on_state_change=None, user_data=None):		"""		group -- list for radio buttons in same group		label -- markup for radio button label		state -- False, True, "mixed" or "first True"		on_state_change -- callback function for state changes		                   on_state_change( radio_button, new_state,				                    user_data=None)	        user_data -- additional param for on_press callback,		             ommited if None for compatibility reasons		This function will append the new radio button to group.		"first True" will set to True if group is empty.		"""		self.__super.__init__(None) # self.w set by set_state below		if state=="first True":			state = not group		self.group = group		self.label = Text("")		self.state = None		self.on_state_change = on_state_change		self.user_data = user_data		self.set_label(label)		self.set_state(state)			group.append(self)		def set_label(self, label):		"""Change the check box label."""		self.label.set_text(label)		self._invalidate()		def get_label(self):		"""Return label text."""		text, attr = self.label.get_text()		return text		def set_state(self, state, do_callback=True):		"""		Call on_state_change if do_callback is True,		then change the radio button state.		if state is True set all other radio buttons in group to False.		"""		if (do_callback and self.state is not None and 			self.on_state_change):			if self.user_data is None:				self.on_state_change(self, state)			else:				self.on_state_change(self, state,						     self.user_data)		self.state = state		self.w = Columns( [			('fixed', self.reserve_columns, self.states[state] ),			self.label ] )		self.w.focus_col = 0				self._invalidate()		if state is not True:			return		for cb in self.group:			if cb is self: continue			if cb.state:				cb.set_state(False)		def get_state(self):		"""Return the state of the radio button."""		return self.state	def keypress(self, (maxcol,), key):		"""Set state to True on space or enter."""		if key not in (' ','enter'):			return key

⌨️ 快捷键说明

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