How to display the file path in Entry widget in windows path format - python-2.7

I have written a Tkinter program in which the Browse button is used to select a file and the selected file's complete path gets displayed in the Entry widget. But my problem is, it's displaying the path with 'forward'(/) slashes instead of the conventional windows format of 'backward'(\) slashes. This is strange for me since I'm working on windows os.
Why this occurs ? Is there any before hand fix for this, instead of replace string option ?
my code:
def selectfile():
fileName = askopenfilename(parent=root, title='Choose a file', initialdir='C:\\')
custName.set(fileName) #Populate the text field with the selected file
#create the 'filepath' field
custName = StringVar(None)
filepath = Entry(root, width ='50', textvariable=custName).pack(anchor=W)
#Create the 'Browse' button
browseButton = Button(root, text="Browse", relief = 'raised', width=8, command=selectfile, cursor='hand2').place(x=325,y=16)
Expected Output in Entry widget:
c:\data\file.txt
Actual Output in Entry widget:
c:/data/file.txt

You can always use replace() to replace "/" with "\" for string. Here's link with docs about replace() method:
https://docs.python.org/2/library/string.html?highlight=replace#string.replace
This is workaround fix. Try looking more deeply inside Tkinter's docs for actual answer why this occurs.

Related

Sublime Text Plugin Open file symbol

I was trying to execute a command to open a file at the line of a text symbol.
I tried to achieve that using the show_overlay command, but it will not open correctly if you try to use the ‘#’ in the search.
Example. create a project that contains a file,
app/code/community/MagicToolbox/MagicZoomPlus/Model/Observer.php:
class MagicToolbox_MagicZoomPlus_Model_Observer {
public function fixLayoutUpdates($observer) {
}
}
if you try to create a plugin with command like this:
class MyPluginCommand(sublime_plugin.TextCommand):
def run(self, view):
sublime_api.window_run_command(
self.view.window().id(),
'show_overlay',
{
'overlay': 'goto',
'show_files': True,
'text': 'MagicToolbox/MagicZoomPlus/Model/Observer#fixLayoutUpdates'
}
)
it will not display the file on first hand. but if you remove all the text from the search input, and then paste it again MagicToolbox/MagicZoomPlus/Model/Observer#fixLayoutUpdates it will display the file and highlight the function.
Maybe there is another way to achieve the same.
After some investigation, it looks like when you provide text to the show_overlay it's just applied directly to the contents of the text field and used as a simple filter for initial display without any of the extra handling that would occur if you entered the text manually. Thus when you insert text that includes special goto features such as the # that you're using here, it's applied strictly as a filter on the files being displayed but no extra action happens.
As you've noted, opening the overlay and then entering the text as two actions has the desired effect. So in order to do this via a plugin, you need to do this in two actions:
import sublime
import sublime_plugin
class ExampleCommand(sublime_plugin.TextCommand):
def run(self, edit):
self.view.window().run_command("show_overlay", {
"overlay": "goto",
"show_files": True
})
self.view.window().run_command("insert", {
"characters": "Observer#fixLayoutUpdates"
})
Here we first open the overlay and then use the insert command to insert the text. The important key here is asking the window to run the insert command. Although insert is a TextCommand, asking the window to execute it tells the window to forward the command to whatever view happens to have the input focus in that window, which is the input area in the overlay.
If the command that you're doing this in isn't modifying the selection or contents of the file on it's own, you can shorten this up by making it a WindowCommand instead and using self.window instead of self.view.window().

Python Tkinter text editor does not save font to text file

Currently, I am working on a GUI text editor with python and tkinter. Thanks to the great people at SO (thank you Rinzler), I have managed to modify the font of the text. However, I am unable to save the font and font size to the txt file.
I know that this should be possible as Notepad can modify and save a txt file with a specified font.
This is the code to save to a file:
def file_saveas():
filename = tkFileDialog.asksaveasfile(mode='w', defaultextension=".txt")
if filename is None: # asksaveasfile return `None` if dialog closed with "cancel".
return
text2save = str(textPad.get(1.0, END)) # starts from `1.0`, not `0.0`
filename.write(text2save)
filename.close()
print filename
This is the code (courtesy of Rinzler) to change the font:
def choose_font():
global root, textPad # I hate to use global, but for simplicity
t = Tkinter.Toplevel()
font_name = Tkinter.Label(t, text='Font Name: ')
font_name.grid(row=0, column=0, sticky='nsew')
enter_font = Tkinter.Entry(t)
enter_font.grid(row=0, column=1, sticky='nsew')
font_size = Tkinter.Label(t, text='Font Size: ')
font_size.grid(row=1, column=0, sticky='nsew')
enter_size = Tkinter.Entry(t)
enter_size.grid(row=1, column=1, sticky='nsew')
# associating a lambda with the call to text.config()
# to change the font of text (a Text widget reference)
ok_btn = Tkinter.Button(t, text='Apply Changes',
command=lambda: textPad.config(font=(enter_font.get(),
enter_size.get())))
print font
ok_btn.grid(row=2, column=1, sticky='nsew')
done = Tkinter.Button(t, text='Get rid of Pushy!', command=t.destroy)
done.grid(row=4, column=1, sticky='nsew')
# just to make strechable widgets
# you don't strictly need this
for i in range(2):
t.grid_rowconfigure(i, weight=1)
t.grid_columnconfigure(i, weight=1)
t.grid_rowconfigure(2, weight=1)
Finally, this is the code that reads the font and other configuration information:
font = (fontname, size)
textPad.config(
borderwidth=0,
font=font ,
foreground="green",
background="black",
insertbackground="white", # cursor
selectforeground="blue", # selection
selectbackground="#008000",
wrap="word",
width=64,
undo=True, # Tk 8.4
)
I have searched the internet without coming up with any answers as to why the font and text size are not saved. Any help would be greatly appreciated.
I am using python 2.7.7 , Tkinter, and this is being run on Windows 7.
Any help manipulation an rtf file would also be helpful (currently, I see the tags and not the end format).
There is no support for this in tkinter. You will have to pick a file fomat that supports fonts (rtf, .docx, .html, etc), convert the data in the widget to this format, and then write it to a file.
Notepad can only have a custom font and size for its editor window, it doesn't save it to the file, it just remembers the user's custom settings, and applies them to its window when you use it.
The tkinter text widget can be horrible to save formatting to another format, I've tried converting it to XML to save to a .docx but I haven't been successful. I have used my own format which is a plain text file with an 'index' of the tkinter Text widget tags at the start and their line&column indexes, then a marker for where the document begins, then the document. This cannot hold images though, and it opens with all the formatting index when you open it in another word processor.
XML is ideal for opening and saving the tkinter text contents - use an xml parser to open, then wite a recursive function to add text with tags as you go. (If you want rich text, this, like xml, is an iterative format - elements inside elements, so could be done like i'm describing below for xml, but you need to write your own rich text parser)
import xml.etree.ElementTree as etree
e = etree.fromstring(string)
#create an element tree of the xml file
insert_iter(e)
#call the recursive insert function
def insert_iter(element):
#recursive insert function
text.insert("end", element.text, tagname)
#insert the elements text
for child in element:
insert_iter(child)
#iterate through the element's child elements, calling the recursive function for each
text.insert("end", child.tail, tagname)
#insert the text after the child element
text.tag_config(tagname, **attrib)
#configure the text
'attrib' is a dictionary eg. {"foreground":"red", "underline":True} would make the text you insert have red font and black underline,
'tagname' is a random string, and needs to be automatically created by your program
To save the file, make a function to do the reverse. I wouldn't bother with using the xml library for this - as tkinter outputs the correct format, just write it manually, but make sure to escape it
from xml.sax.saxutils import escape
data = text.dump("1.0", "end")
print(data[0:500]) # print some of the output just to show how the dump method works
output = ''
#get contents of text widget (including all formatting, in order) and create a string to add the output file to
for line in data:
if line[0] == "text":
#add the plain text to the output
output += escape(line[1])
elif line[0] == "tagon":
#add a start xml tag, with attributes for the given tkinter tag
name = 'font'
attrib = ""
tag = #the dictionary you stored in your program when creating this tag
for key in tag:
attrib += "%s='%s' "%(key, escape(tag[key]))
output += "<%s %s>"%(name, attrib)
elif line[0] == "tagoff":
#add a closing xml tag
output += '</%s>'%name

WXPython: getting the initial value of a combo box

In a dialog box I have a combo box and a text field. I would like to make so that if one particular value in the combo box is selected, the text field would be disabled (or hidden), and if another value is selected, the text field would be enabled.
I have:
self.myCombo = wx.ComboBox(parent=self, choices=['value1', 'value2'], style = wx.CB_READONLY)
self.myCombo.Bind(wx.EVT_COMBOBOX, self.onChange)
# ...
def onChange(self, ev):
self.myTextField.Enable(False) if self.myCombo.GetValue() != "value1" else self.myTextField.Enable(True)
And this does work like a charm, the text field gets enabled and disabled.
However, I would like to have the text field enabled or disabled depending on the initial value of the combo box, meaning the value gotten from a config file and selected when the dialog box is open.
I've tried the same:
self.myTextField = wx.TextCtrl(parent=self)
self.myTextField.Enable(False) if self.myCombo.GetValue() != "value1" else self.myTextField.Enable(True)
but this doesn't work. I've tried GetSelection also, but when logging this, both GetValue and GetSelection return -1.
The combobox probably isn't fully initialized yet when you try to query it. If you want to disable it when it loads, you don't have to check its value. Just disable it. But for what you want to do, I would recommend using wxPython's wx.CallAfter() method.
Something like the following should suffice:
def __init__(self):
# initialize various variables
wx.CallAfter(self.check_combobox, args)
def check_combobox(self, args):
self.myTextField.Enable(False) if self.myCombo.GetValue() != "value1" else self.myTextField.Enable(True)

Getting the name and location of selected file Qt

I have a program in which I have a button to get File Dialog like
How can I select a file, get the file name and location, and save that to a string displayed in the ui.The signalclicked(), emitted from the button, is connected to the slot fileSELECT().
........
void MainThread::fileSELECT(){
QString fileName = QFileDialog::getOpenFileName(this,tr("Select video"),"d:\\BMDvideos",tr("Video files (*.avi)"));
}
so when I select an .avi file, how do I get its location in fileName displayed like
d:\BMDvideo\videFile.avi
so I thinks that I got it now. my first code was completly wrong.
void MainThread::fileSelect(){
QString fileName = QFileDialog::getOpenFileName(this,tr("Select video"),"d:\\BMDvideos",tr("Video files (*.avi)"));
QLabel *testLabel = new QLabel(fileName);
BOX->addWidget(testLabel);
}
I can see now the path of the selected file
To get the folder path, you can use QFileDialog::getExistingDirectory, and to get the file-name use QFileDialog::getOpenFileName

Tidy way to delete image from Gtk::TreeStore

I have an dialog window with Gtk::TreeView. This dialod shows main filesystem tree
and provides option to select folders on the disk. When user selects some folder, I am
adding an Gtk::Stock image to the row that represents that folder.
To do this, I have created an Gtk::CellRendererPixbuf associated with the last column of my tree:
//appending columns
directory_tree.append_column("Folder List", dir_columns.name);
Gtk::TreeViewColumn *column = directory_tree.get_column(0);
if(column) column->set_expand(true);
Gtk::CellRendererPixbuf *cell = Gtk::manage(new Gtk::CellRendererPixbuf);
directory_tree.append_column("", *cell);
column = directory_tree.get_column(1);
if(column) column->add_attribute(cell->property_stock_id(), dir_columns.stock_id);
Link to this bit of code: https://github.com/mc-suchecki/Imagine/blob/master/gui/dialogs.cpp#L47
Gtk::CellRendererPixbuf 'translates' Gtk::StockId found in 'dir_columns.stock_id'
to an image located in tree. When I add image to row like this:
//selecting folder
(*folder)[fs_columns.stock_id] = Gtk::StockID(Gtk::Stock::FIND).get_string();
(*folder)[fs_columns.included] = true;
everything is ok, but when I try to delete the image this way:
//unselecting folder
(*folder)[fs_columns.stock_id] = "";
(*folder)[fs_columns.included] = false;
the image correctly disappears, but there are some errors in command line like this (this is not the exact message, I will post it when I will be able to launch my application):
(imagine:9376): Gtk-WARNING **: Gtk StockId not found
Of course the reason of the warning is obvious (there is no StockId item associated with blank name), however my question is: Is there a way to delete an image from Gtk::TreeView row which would not generate any Gtk warnings?
Code where i deselect folder is here:
https://github.com/mc-suchecki/Imagine/blob/master/core/core.cpp#L207
Thank you very much in advance and sorry for my English.
Change the visible property to false if you want to get rid of the image, instead of the stock-id property.