Are there any toolkit libraries for curses with Python bindings? - python

I'm writing a text-based hex viewer for fun and usefulness(I intend to add syntax highlighting for many different filetypes), and am wondering if there are any curses toolkits I could use.
I will probably write something myself anyway as to familiarize myself with the way gui toolkits work, but it would be nice to know of useful libraries for future reference for myself and others.

Urwid is the best library to work with curses and python that I know.
Altenatively, you might find also interesting snack (newt-based library).
For more information, please have a look at this question.

npyscreen
Npyscreen is a Python widget library and application framework for programming terminal or console applications. It is built on top of ncurses, which is part of the standard library.
The focus of this library is to provide a rapid way to develop console applications. In general, adding a control to the screen requires only one line of code.
This framework should be powerful enough to create everything from quick, simple programs to complex, multi-screen applications.
#!/usr/bin/env python
# encoding: utf-8
import npyscreen
class TestApp(npyscreen.NPSApp):
def main(self):
# These lines create the form and populate it with widgets.
# A fairly complex screen in only 8 or so lines of code - a line for each control.
F = npyscreen.Form(name = "Welcome to Npyscreen",)
t = F.add(npyscreen.TitleText, name = "Text:",)
fn = F.add(npyscreen.TitleFilename, name = "Filename:")
fn2 = F.add(npyscreen.TitleFilenameCombo, name="Filename2:")
dt = F.add(npyscreen.TitleDateCombo, name = "Date:")
s = F.add(npyscreen.TitleSlider, out_of=12, name = "Slider")
ml = F.add(npyscreen.MultiLineEdit,
value = """try typing here!\nMutiline text, press ^R to reformat.\n""",
max_height=5, rely=9)
ms = F.add(npyscreen.TitleSelectOne, max_height=4, value = [1,], name="Pick One",
values = ["Option1","Option2","Option3"], scroll_exit=True)
ms2= F.add(npyscreen.TitleMultiSelect, max_height =-2, value = [1,], name="Pick Several",
values = ["Option1","Option2","Option3"], scroll_exit=True)
# This lets the user interact with the Form.
F.edit()
print(ms.get_selected_objects())
if __name__ == "__main__":
App = TestApp()
App.run()

On GitHub there is a free to use, study, modify and re-distribute High Level GUI library, at "https://github.com/rigordo959/tsWxGTUI_PyVx_Repository".
It is implemented in Python 2x & 3x using the "curses" Low Level GUI package.
Your application programs can be programmed using a character-mode subset of the pixel-mode "wxPython" High Level GUI API. It supports displays with keyboard and mouse input and various terminal emulators including the color xterms (8-color with 64-color pairs and 16-color with 256-color pairs) and non-color vt100/vt220.

Related

How to set initial directory in GTK3 FileChooser in Python?

EDIT: Solution found and shown in code below.
Python noob here. I usually like to find answers myself, but I'm striking out on this one.
I simply want to set the directory the user starts in when FileChooser opens (rather than have the Python working directory).
This seems like such a simple thing and a common need, I am surprised and frustrated that I could not find anything in Glade (which I used to create the FileChooser), nor in any online GTK documentation.
So... how can this be done?
As mentioned I built the xml file with Glade and loaded it with gtk.builder.
Thanks much for any help
CODE WITH (A) SOLUTION
def GetFile():
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
chosenfile = None
class Handler:
def on_destroy(self, *args):
Gtk.main_quit()
def on_OK_clicked(self, *args):
nonlocal chosenfile
chosenfile = window.get_filename()
Gtk.main_quit()
def on_cancel_clicked(self, *args):
nonlocal chosenfile
chosenfile = "CANCELLED"
Gtk.main_quit()
builder = Gtk.Builder()
builder.add_from_file("mod_FileChoose.glade")
builder.connect_signals(Handler())
window = builder.get_object("FileSelector")
#HERE IS THE LINE IN QUESTION
Gtk.FileChooser.set_current_folder(window, "/home/")
window.show_all()
Gtk.main()
return chosenfile
I should add that in GTK API source where I found this, it states:
"In general, you should not use this function. See the section on setting up a file chooser dialog[gtkfilechooserdialog-setting-up] for the rationale behind this."
So far I have not found the setting-up section with rationale for not using or better approach.
Source: gtk API ref
It seems to be okay to use the set_current_folder method as to the mentioned "setup section" that can be found here:
Note that old versions of the file chooser’s documentation suggested using gtk_file_chooser_set_current_folder() in various situations, with the intention of letting the application suggest a reasonable default folder. This is no longer considered to be a good policy, as now the file chooser is able to make good suggestions on its own. In general, you should only cause the file chooser to show a specific folder when it is appropriate to use gtk_file_chooser_set_filename(), i.e. when you are doing a Save As command and you already have a file saved somewhere.
Addtional info: to look up docs, I use the DevHelp tool on Linux. Most Gtk docs (for python) for it can be found on this github repo. The offical online docs for Gtk3 should be these.

Return carriage back to 0,0 in Python 2.6

Im trying to display a grid with moving individuals within it. At the moment im using a "clear screen" then display the grid. This is messy as the screen "flickers" every time.
In C and VB.NET there was methods of forcing the carriage to go back to the start of the console and overwrite content. This removed the flicker.
Is it possible in Python to do this? I've Googled around, and i found Curses, but thats Unix only (and i'll be working primarily within Windows).
Current Grid code (super basic):
#Clear() is a OS indepedent method of clearing the screen defined in code above, in windows its just os.system('cls')
clear()
x=0
y=0
tiles=""
tile=""
# Generate grid
while(y<max_y):
while(x<max_x):
tile = tileGen(x,y)
tiles += str(tile)
x+=1
tiles += "\n"
y+=1
x=0
print(tiles)
Maybe this will help: ANSI Escape Sequences
The Home command would be '\x1b[0;0H'.
For what it's worth, a python package does exist that wraps PDCurses, a windows-compatible curses library. The package, UniCurses, provides a uniform interface to either PDCurses (under windows) or python's native curses module, and so can be used to write cross-platform curses apps. It may be that Mike Desimone's answer is enough for your needs though.

How to embed some application window in my application using any Python GUI framework

I want some application to look like widget inside my Python application.
That's all. I dont need any interaction between them. I'm interested in solutions in any GUI toolkit for both windows and x windows.
It would be nice to have a solution with Tkinter but it's not crucial.
Using GTK on X windows (i.e. Linux, FreeBSD, Solaris), you can use the XEMBED protocol to embed widgets using gtk.Socket. Unfortunately, the application that you're launching has to explicitly support it so that you can tell it to embed itself. Some applications don't support this. Notably, I can't find a way to do it with Firefox.
Nonetheless, here's a sample program that will run either an X terminal or an Emacs session inside a GTK window:
import os
import gtk
from gtk import Socket, Button, Window, VBox, HBox
w = Window()
e = Button("Emacs")
x = Button("XTerm")
s = Socket()
v = VBox()
h = HBox()
w.add(v)
v.add(s)
h.add(e)
h.add(x)
v.pack_start(h, expand=False)
def runemacs(btn):
x.set_sensitive(False); e.set_sensitive(False)
os.spawnlp(os.P_NOWAIT, "emacs",
"emacs", "--parent-id", str(s.get_id()))
def runxterm(btn):
x.set_sensitive(False); e.set_sensitive(False)
os.spawnlp(os.P_NOWAIT, "xterm",
"xterm", "-into", str(s.get_id()))
e.connect('clicked', runemacs)
x.connect('clicked', runxterm)
w.show_all()
gtk.main()
Not enough reputation to comment on Glyphs answer. To make xterm work, in addition to the comments above one needs to also add
XTerm*allowSendEvents: True
to ~/.Xresources. (and perhaps reload those, with xrdb -load ~/.Xresources)

What are the steps to convert from using libglade to GtkBuilder? (Python)

I have a small project that uses libglade and use the following to load the xml file:
self.gladefile = "sdm.glade"
self.wTree = gtk.glade.XML(self.gladefile)
self.window = self.wTree.get_widget("MainWindow")
if (self.window):
self.window.connect("destroy", gtk.main_quit)
dic = { "on_button1_clicked" : self.button1_clicked,
"on_MainWindow_destroy" : gtk.main_quit}
self.wTree.signal_autoconnect(dic)
After converting my project in glade, what structural changes do I need to make?
I'm on Ubuntu 9.04.
You need to use gtk.Builder instead. This class can load any number of UI files, so you need to add them manually, either as files or as strings:
self.uifile = "sdm.ui"
self.wTree = gtk.Builder()
self.wTree.add_from_file(self.uifile)
Instead of get_widget, just use get_object on the builder class:
self.window = self.wTree.get_object("MainWindow")
if self.window:
self.window.connect("destroy", gtk.main_quit)
To connect the signals, just use connect_signals, which also takes a dictionary:
dic = { "on_button1_clicked" : self.button1_clicked,
"on_MainWindow_destroy" : gtk.main_quit}
self.wTree.connect_signals(dic)
It used to be the case (at least in GTK+ 2.12, not sure if it's still the same) that you could call connect_signals only once, any signals which are not connected during the first invocation will never be connected. This was different in glade, so be careful if you relied on that feature before.
Torsten's answer is correct, but a little incomplete, so in the spirit of http://xkcd.com/979/ here is the procedure I recently settled on after much trial-and-error:
Open yada.glade in Glade interface designer. Go to edit->project and change the project type to GtkBuilder and make sure it targets the latest version (2.24 as of this writing). Save the file, being sure that it saves in GtkBuilder format, and change the name from yada.glade to yada.ui
Open yada.py and change the following code:
gladefile = relativize_filename(os.path.join("glade", "yada.glade"))
self.wTree = gtk.glade.XML(gladefile, self.windowname)
to:
uifile = relativize_filename(os.path.join("glade", "yada.ui"))
self.wTree = gtk.Builder()
self.wTree.add_from_file(uifile)
Similarly change all instances of self.wTree.get_widget(...) to self.wTree.get_object(...)
Change self.wTree.signal_autoconnect(dic) to self.wTree.connect_signals(dic)
If your code depends on the name assigned the widget in the interface designer, change widget.get_name() to gtk.Buildable.get_name(widget). widget.get_name() now just returns the widget type. EDIT: You also need to change widget.set_name('my_widget') to gtk.Buildable.set_name(widget, 'my_widget').
Delete import gtk.glade
I found numerous unused signals defined in the yada.ui xml file, I had to open the xml file and manually delete them to eliminate the warnings they caused.

The OLE way of doing drag&drop in wxPython

I have wxPython app which is running on MS Windows and I'd like it to support drag&drop between its instances (so the user opens my app 3 times and drags data from one instance to another).
The simple drag&drop in wxPython works that way:
User initiates drag: The source window packs necessary data in wx.DataObject(), creates new wx.DropSource, sets its data and calls dropSource.DoDragDrop()
User drops data onto target window: The drop target calls library function GetData() which transfers actual data to its wx.DataObject instance and finally - dataObject.GetData() unpacks the actual data.
I'd like to have some more sophisticated drag&drop which would allow user to choose what data is dragged after he drops.
Scenario of my dreams:
User initiates drag: Only some pointer to the source window is packed (some function or object).
User drops data onto target window: Nice dialog is displayed which asks user which drag&drop mode he chooses (like - dragging only song title, or song title and the artists name or whole album of the dragged artist).
Users chooses drag&drop mode: Drop target calls some function on the dragged data object, which then retrieves data from the drag source and transfers it to the drop target.
The scenario of my dreams seems doable in MS Windows, but the docs for wxWidgets and wxPython are pretty complex and ambigious. Not all wx.DataObject classes are available in wxPython (only wx.PySimpleDataObject), so I'd like someone to share his experience with such approach. Can such behaviour be implemented in wxPython without having to code it directly in winAPI?
EDIT:
Toni Ruža gave an answer with working drag&drop example, but that's not exactly the scenario of my dreams. His code manipulates data when it's dropped (the HandleDrop() shows popup menu), but data is prepared when drag is initiated (in On_ElementDrag()). In my application there should be three different drag&drop modes, and some of them require time-consuming data preparation. That's why I want to postpone data retrieval to the moment user drops data and chooses (potentially costly) d&d mode.
And for memory protection issue - I want to use OLE mechanisms for inter-process communication, like MS Office does. You can copy Excel diagram and paste it into MS-Word where it will behave like an image (well, sort of). Since it works I believe it can be done in winAPI. I just don't know if I can code it in wxPython.
Since you can't use one of the standard data formats to store references to python objects I would recommend you use a text data format for storing the parameters you need for your method calls rather than making a new data format. And anyway, it would be no good to pass a reference to an object from one app to another as the object in question would not be accessible (remember memory protection?).
Here is a simple example for your requirements:
import wx
class TestDropTarget(wx.TextDropTarget):
def OnDropText(self, x, y, text):
wx.GetApp().TopWindow.HandleDrop(text)
def OnDragOver(self, x, y, d):
return wx.DragCopy
class Test(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
self.numbers = wx.ListCtrl(self, style = wx.LC_ICON | wx.LC_AUTOARRANGE)
self.field = wx.TextCtrl(self)
sizer = wx.FlexGridSizer(2, 2, 5, 5)
sizer.AddGrowableCol(1)
sizer.AddGrowableRow(0)
self.SetSizer(sizer)
sizer.Add(wx.StaticText(self, label="Drag from:"))
sizer.Add(self.numbers, flag=wx.EXPAND)
sizer.Add(wx.StaticText(self, label="Drag to:"), flag=wx.ALIGN_CENTER_VERTICAL)
sizer.Add(self.field)
for i in range(100):
self.numbers.InsertStringItem(self.numbers.GetItemCount(), str(i))
self.numbers.Bind(wx.EVT_LIST_BEGIN_DRAG, self.On_ElementDrag)
self.field.SetDropTarget(TestDropTarget())
menu_id1 = wx.NewId()
menu_id2 = wx.NewId()
self.menu = wx.Menu()
self.menu.AppendItem(wx.MenuItem(self.menu, menu_id1, "Simple copy"))
self.menu.AppendItem(wx.MenuItem(self.menu, menu_id2, "Mess with it"))
self.Bind(wx.EVT_MENU, self.On_SimpleCopy, id=menu_id1)
self.Bind(wx.EVT_MENU, self.On_MessWithIt, id=menu_id2)
def On_ElementDrag(self, event):
data = wx.TextDataObject(self.numbers.GetItemText(event.Index))
source = wx.DropSource(self.numbers)
source.SetData(data)
source.DoDragDrop()
def HandleDrop(self, text):
self._text = text
self.PopupMenu(self.menu)
def On_SimpleCopy(self, event):
self.field.Value = self._text
def On_MessWithIt(self, event):
self.field.Value = "<-%s->" % "".join([int(c)*c for c in self._text])
app = wx.PySimpleApp()
app.TopWindow = Test()
app.TopWindow.Show()
app.MainLoop()
Methods like On_SimpleCopy and On_MessWithIt get executed after the drop so any lengthy operations you might want to do you can do there based on the textual or some other standard type of data you transfered with the drag (self._text in my case), and look... no OLE :)
Ok, it seems that it can't be done the way I wanted it.
Possible solutions are:
Pass some parameters in d&d and do some inter-process communication on your own, after user drops data in target processes window.
Use DataObjectComposite to support multiple drag&drop formats and keyboard modifiers to choose current format. Scenario:
User initiates drag. State of CTRL, ALT and SHIFT is checked, and depending on it the d&d format is selected. DataObjectComposite is created, and has set data in chosen format.
User drops data in target window. Drop target asks dropped DataObject for supported format and retrieves data, knowing what format it is in.
I'm choosing the solution 2., because it doesn't require hand crafting communication between processes and it allows me to avoid unnecessary data retrieval when user wants to drag only the simplest data.
Anyway - Toni, thanks for your answer! Played with it a little and it made me think of d&d and of changing my approach to the problem.

Categories

Resources