Alternative for tkinter's askopenfilename - python-3.x

Currently I am using tkinter's askopenfilename in a quicklist editor for Ubuntu to get a file's name and location. Although it works fine, the look and feel is not native.
Is there an easy alternative dialogue window, to navigate and get a file's name and location?

You could try with wxPython FileDialog:
>>> import wx
>>> d = wx.FileDialog(None)
>>> d.ShowModal()
5101
>>>
It gives a more OS specific look
wxPython is arriving soon to py3k as the Phoenix project and there are already snapshots for windows and mac (see my comment below). If you want something more stable you can use pyQt QtGui.QFileDialog.
import sys
from PyQt4 import QtGui
class Dialog(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
filename = QtGui.QFileDialog.getOpenFileName()
print filename
app = QtGui.QApplication(sys.argv)
dialog = Dialog()
You have a more complete example here.

Zenity
Zenity's File Selection Dialog provides an easy and natively looking solution with the --file-selection option. The dialog provides a number of options.
See also Zenity's man pages.
In its simplest form:
#!/usr/bin/env python3
import subprocess
try:
file = subprocess.check_output(["zenity", "--file-selection"]).decode("utf-8").strip()
print(file)
except subprocess.CalledProcessError:
pass
Gtk's FileChooserDialog
Another option is Gtk's FileChooserDialog, which produces, as one might expect, perfectly natively looking file chooser dialog windows.

Related

How to copy-paste data from an OS-running application with Python?

I need to write an application that basically focuses on a given Windows window title and copy-pastes data in a notepad. I've managed to achieve it with pygetwindow and pyautogui, but it's buggy:
import pygetwindow as gw
import pyautogui
# extract all titles and filter to specific one
all_titles = gw.getAllTitles()
titles = [title for title in all_titles if 'title' in title]
window = gw.getWindowsWithTitle(titles[0])[0].activate()
pyautogui.hotkey('ctrl', 'a')
pyautogui.hotkey('ctrl', 'c')
Using Spyder, I ocasionally get the following error when activating:
PyGetWindowException: Error code from Windows: 126 - The specified module could not be found.
Additionally, I would be interested in doing this process without affecting the user working on the machine. Activate basically makes the window pop to front. Moreover, it would be better to not be OS dependant, but I haven't found anything yet.
I've tried pywinauto but the SetFocus() method doesn't work (it's buggy, documented).
Is there any other method which would make the whole process invisible and easier?
Not sure if this will help
I am using pywinauto to set_focus
import pywinauto
import pygetwindow as gw
def focus_to_window(window_title=None):
window = gw.getWindowsWithTitle(window_title)[0]
if not window.isActive:
pywinauto.application.Application().connect(handle=window._hWnd).top_window().set_focus()

I want to embed python console in my tkinter window.. How can i do it?

I am making a text editor and want to add a feature of IDLE in my app. So i want an frame with python IDLE embedded in it with all menus and features which original python IDLE gives.
I looked in source of idle lib but cannot find a solution.
try:
import idlelib.pyshell
except ImportError:
# IDLE is not installed, but maybe pyshell is on sys.path:
from . import pyshell
import os
idledir = os.path.dirname(os.path.abspath(pyshell.__file__))
if idledir != os.getcwd():
# We're not in the IDLE directory, help the subprocess find run.py
pypath = os.environ.get('PYTHONPATH', '')
if pypath:
os.environ['PYTHONPATH'] = pypath + ':' + idledir
else:
os.environ['PYTHONPATH'] = idledir
pyshell.main()
else:
idlelib.pyshell.main()
This code is of pyshell.pyw found under idlelib folder in all python install
I searched the idle.pyw and found that it uses a program pyshell which is real shell. So how can i embed it.
I want a Tkinter frame with python IDLE shell embedded in it.Please give the code. Thanks in advance.
idlelib implements IDLE. While you are free to use it otherwise, it is private in the sense that code and interfaces can change in any release without the usual back-compatibility constraints. Import and use idlelib modules at your own rish.
Currently, a Shell window is a Toplevel with a Menu and a Frame. The latter has a Text and vertical Scrollbar. It is not possible to visually embed a Toplevel within a frame (or within another Toplevel or root = Tk()). top = Toplevel(myframe) works, but top cannot be placed, packed, or gridded within myframe.
I hope in the future to refactor editor.py and pyshell.py so as to separate the window with menu from the frame with scrollable text. The result should include embeddable EditorFrame and ShellFrame classes that have parent as an arguments. But that is in the future.
Currently, one can run IDLE from within python with import idlelib.idle. However, because this runs mainloop() (on its own root), it blocks and does not finish until all IDLE windows are closed. This may not be what one wants.
If having Shell run in a separate window is acceptable, one could extract from python.main the 10-20 lines needed to just run Shell. Some experimentation would be needed. If the main app uses tkinter, this function should take the app's root as an argument and not call mainloop().
Tcl having Tkcon.tcl . when each thread source (means run/exec) the Tkcon.tcl
each thread will pop up a Tk shell/Tk console/tkcon.tcl very good idea for debug. and print message individually by thread.
Python having idle.py ... and how to use it ? still finding out the example .
The are same Tk base . why can't find an suitable example? so far ... keep finding...

PyQt5 GUI freeze caused by Windows focus-follows-mouse

When Windows focus-follows-mouse-without-raising-the-window is enabled by either of the two methods linked to below, I consistently get PyQt5 GUI 'freezes' where you have to type any character in the terminal that you ran python from in order to unfreeze the GUI; complete description and test case (Windows 10, Python 3.6.1, PyQt5) is here: pyqt5 click in terminal causes GUI freeze
To enable the focus-follows-mouse-without-raise behavior, try either of these - they both work in Windows 10:
downloadable program ('X-Mouse' though that name is used by other programs):
https://joelpurra.com/projects/X-Mouse_Controls/
registry hack description:
https://sinewalker.wordpress.com/2010/03/10/ms-windows-focus-follows-mouse-registry-hacks/
So - a few questions:
can anyone reproduce the issue? It seems 100% reproducible for me, but it would be great to hear the same from someone else.
is there a way to change the python code to detect-and-circumvent focus-follows-mouse, or just to be immune to it, i.e. maybe by ensuring the GUI application always takes focus back again when you - for example - click in a dialog or qmessagebox owned by the main GUI window, or by some other means? (Is the object hierarchy set up optimally, and if not, maybe this could all be resolved by correcting the ownership structure?)
The brute-force solution seems to work, though I'd like to leave this question open to see if someone knows of a more optimal solution; it took a fair amount of searching to figure out the right way; mainly by taking a look a the open-source code for X-Mouse. Basically, this method takes effect immediately, whereas the registry hack doesn't take effect until reboot.
New version of pyqt_freeze_testcase.py (the file from the referenced stackoverflow question); the changes are only additions, noted between lines of hash marks:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
####################### added begin:
import win32gui
import win32con
####################### added end
# import the UI file created with pyuic5
from minimal_ui import Ui_Dialog
class MyWindow(QDialog,Ui_Dialog):
def __init__(self,parent):
QDialog.__init__(self)
self.parent=parent
self.ui=Ui_Dialog()
self.ui.setupUi(self)
################################# added begin:
self.initialWindowTracking=False
try:
self.initialWindowTracking=win32gui.SystemParametersInfo(win32con.SPI_GETACTIVEWINDOWTRACKING)
except:
pass
if self.initialWindowTracking:
print("Window Tracking was initially enabled. Disabling it for now; will re-enable on exit.")
win32gui.SystemParametersInfo(win32con.SPI_SETACTIVEWINDOWTRACKING,False)
################################# added end
def showMsg(self):
self.really1=QMessageBox(QMessageBox.Warning,"Really?","Really do stuff?",
QMessageBox.Yes|QMessageBox.No,self,Qt.WindowTitleHint|Qt.WindowCloseButtonHint|Qt.Dialog|Qt.MSWindowsFixedSizeDialogHint|Qt.WindowStaysOnTopHint)
self.really1.show()
self.really1.raise_()
if self.really1.exec_()==QMessageBox.No:
print("nope")
return
print("yep")
################################## added begin:
def closeEvent(self,event):
if self.initialWindowTracking:
print("restoring initial window tracking behavior ("+str(self.initialWindowTracking)+")")
win32gui.SystemParametersInfo(win32con.SPI_SETACTIVEWINDOWTRACKING,self.initialWindowTracking)
################################## added end
def main():
app = QApplication(sys.argv)
w = MyWindow(app)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

QLineEdit.setText only works once in function

I'm currently trying to program for my bachelor thesis. The main part works, so now I want to implement a user interface. I watched some tutorials and worked via trial and error, and my user interface also works. So far so good. But yesterday I changed a small thing and that doesn't do what i want. I have a button saying "start program", and a line-edit where i want to display the current status. My code is:
import sys
from PyQt4 import QtGui
from theguifile import Ui_MainWindow
import otherfile
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui=Ui_MainWindow()
self.ui.setupUi(self)
self.ui.mybutton.clicked.connect(self.runprogram)
def runprogram(self):
self.ui.mylineedit.setText('Running') # doesnt work
try:
otherfile.therealfunction() # works
except ErrorIwanttocatch:
self.ui.mylineedit.setText('thisErrorhappened') # works
else:
self.ui.mylineedit.setText('Success') # works
app = QtGui.QApplication(sys.argv)
window = Main()
sys.exit(app.exec_())
Everything works as I want except from lineedit.setText('Running'). What I want is that "Running" is displayed while otherfile.therealfunction is working. I guess I have to update the line-edit somehow? But until now I didn't figure out how I can do that. I also set the line-edit readonly because I don't want the user to be able to change it, so maybe that's a problem? I thought readonly would only affect what the user can do.
I am using Python3 and PyQt4 with Qt Designer.
Calling otherfile.therealfunction() will block all ui updates until the function completes. You can try forcing immediate ui updates like this:
def runprogram(self):
self.ui.mylineedit.setText('Running')
QtGui.qApp.processEvents()

pyqt+maya = fatal error when click to context menu

i use pyqt in autodesk maya. all work but when i try connect a context menu to my elements - maya get fatal error and closed.
import maya.OpenMayaUI as mui
import maya.api.OpenMaya as om
import sip
from PyQt4 import QtGui, QtCore, uic
#----------------------------------------------------------------------
def getMayaWindow():
ptr = mui.MQtUtil.mainWindow()
return sip.wrapinstance(long(ptr), QtCore.QObject)
#----------------------------------------------------------------------
form_class, base_class = uic.loadUiType('X:/tools/Maya/windows/2014/python/UI/perforceBrowserWnd.ui')
#----------------------------------------------------------------------
# main window class
#----------------------------------------------------------------------
class PerforceWindow(base_class, form_class):
def __init__(self, parent=getMayaWindow()):
super(base_class, self).__init__(parent)
self.setupUi(self)
# Popup Menu is not visible, but we add actions from above
self.popMenu = QtGui.QMenu( self )
self.popMenu.addAction("revert", self.on_action_revert)
self.popMenu.addAction("submit", self.on_action_submit)
self.filesListWgt.customContextMenuRequested.connect( self.filesListWgtMenuRequested )
#------------------------------------------------------------------
def filesListWgtMenuRequested(self, pos):
self.popMenu.exec_( self.filesListWgt.mapToGlobal(pos) )
def on_action_revert(self):
print('on_action_revert')
def on_action_submit(self):
print('on_action_submit')
#----------------------------------------------------------------------
# window
#----------------------------------------------------------------------
def perforceBrowser2():
perforceBrowserWnd = PerforceWindow()
perforceBrowserWnd.show()
perforceBrowser2()
dialog created in qtdesigner. i set attribute contentMenuPolicy in designer on QListWidtet. when i right click on QListWidtet or any element - i see a context menu. but if i click a menu or dismiss it - maya get fatal error
and i see log text - function on_action_revert is called. but after that - maya crashed.
what i doing wrong?
update:
i try simple test. replace a menu to simple call a function:
replace connect to:
self.filesListWgt.customContextMenuRequested.connect( self.on_action_revert )
def on_action_revert(self):
print('on_action_revert')
this crash maya too
I tested your code along with your UI file on PyQt in Maya 2013 as well as on PySide (using a QtShim) on Maya 2014 and your code ran fine. Please check your PyQt build for Maya 2014.
I recommend attempting to run your code using PySide on Maya 2014. To do this you do not need to change any of your code base. You just need to modify a few imports. It is worth checking out these: Take a look at this. You can use this to write code that is compatible in both PyQt and PySide. https://github.com/rgalanakis/practicalmayapython/blob/master/src/chapter5/qtshim.py
And to load your ui file in PySide environment take a look at this article: http://www.jason-parks.com/artoftech/?p=579
PyQt and PySide are both just python wrappers for the Qt framework. They are identical apart from a very few differences. So your code base never needs to change no matter what you use to run it in.
P.s. But for whatever reason you are so particular for using PyQt for 2014, Please use these guides to build it: http://download.autodesk.com/us/support/files/maya_documentation/pyqtmaya2014.pdf and this one: http://around-the-corner.typepad.com/adn/2013/04/building-sip-and-pyqt-for-maya-2014.html
Maya specific PyQt builds are maintained in this Github repo maintained by Marcus Ottosson. You can grab the specific build for yourself and add it to PYTHONPATH. I had the same issue in Maya 2015 and this helped.
https://github.com/pyqt

Resources