I'm using Qt.Gui.QFileDialog.getOpenFileName method to open a file. If I set the default file directory to "/Users/me/Documents/data/2013/today/" the dialog box opens to "/Users/me/Documents/data/2013/" with the "today" folder selected. How do I get the the correct default folder to be opened in the window?
fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file', "/Users/me/Documents/data/2012/20121102/images/",'*.npy')
Opens a dialog box in /Users/me/Documents/data/2012/20121102. I want the window to open in /Users/me/Documents/data/2012/20121102/images/
The most probable reason is that the file doesn't exist at the time you are requesting it be opened. For opening folders use QtGui.QFileDialog.getExistingDirectory:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtGui, QtCore
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonOpen = QtGui.QPushButton(self)
self.pushButtonOpen.setText("Open Folder")
self.pushButtonOpen.clicked.connect(self.on_pushButtonOpen_clicked)
self.layoutHorizontal = QtGui.QHBoxLayout(self)
self.layoutHorizontal.addWidget(self.pushButtonOpen)
#QtCore.pyqtSlot()
def on_pushButtonOpen_clicked(self):
folderName = QtGui.QFileDialog.getExistingDirectory(
self, "Open Directory",
"/path/to/folder",
QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontResolveSymlinks,
)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
For someone's information (even though 8 years passed)
You could pass the directory argument to getOpenFileName for the default folder in PyQt5.
Related
I'm trying to make a gui (Qt Designer) to import an excel file and display the data in the gui.
The script works fine when I run it from within my IDE (Spyder), but if I run it from the command window or by opening the python file from windows explorer, the import function does not work. (The gui starts up fine but when the import button is pressed and the file is selected, nothing happens and no error is produced. When running from Spyder, the data is imported and displayed in the gui as expected).
If I pre-select the file location (commented out in the code below), then the script works fine from the command line or by clicking from explorer.
Thanks for any help!
Python 2.7 (Anaconda), Windows 10, PyQt4
import sys
from PyQt4 import QtGui
from excel_import_gui import Ui_MainWindow
import xlrd
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.setupSignals()
def set_import_data(self,data_to_import,table_to_change):
for row in range(len(data_to_import)):
for col in range(len(data_to_import[0])):
table_to_change.setRowCount(len(data_to_import))
table_to_change.setColumnCount(len(data_to_import[0]))
item = data_to_import[row][col]
table_to_change.setItem(row,col,QtGui.QTableWidgetItem(str(item)))
def setupSignals(self):
self.ui.importData_btn.clicked.connect(self.select_file)
def select_file(self):
excel_file = QtGui.QFileDialog.getOpenFileName(self,
"Select Excel file to import","","Excel (*.xls *.xlsx)")
# excel_file = "C:/Users/Ben/Work/Python tests/Qt GUIs/Excel_import_GUI/fish_test.xlsx"
if excel_file:
open_excel_file = xlrd.open_workbook(excel_file)
self.start_import_data(open_excel_file)
def start_import_data(self, workbook):
#import data from excel file
workbook_data = []
for sheetNum in range (workbook.nsheets):
worksheet = workbook.sheet_by_index(sheetNum)
workbook_data.append([[worksheet.cell_value(row,col) for col in range (worksheet.ncols)] for row in range(worksheet.nrows)])
# Set each worksheet of workbook_data to each tab in GUI widget
self.set_import_data(workbook_data[0],self.ui.fish_table)
self.set_import_data(workbook_data[1],self.ui.boats_table)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
Well I found a solution myself by converting the excel_file variable to a string.
excel_file = str(QtGui.QFileDialog.getOpenFileName(self, "Select Excel file to import","","Excel (*.xls *.xlsx)"))
I created a simple GUI in python 3.4 using tkinter 8.5. I used cx_freeze to build an exe from this GUI. Now when I run this exe, sometimes I notice that the program still shows under 'Background Processes' in Task Manager even after I terminate it using a Quit button or using the close button in the window.
The GUI works like this: You select a file type from a drop down list, read the file using a command button and save it as a separate file. Now this problem happens only if I close the GUI after using it. If I simply open the GUI and close it using the Quit button or close button, it does not stay as a background process.
Is it normal for it to behave like this? If not what can I do to terminate it properly?
The simplified code for the GUI is given below. The function 'fileselect' calls functions from the module 'dataselect'. If needed, I will provide the code for the 'dataselect' module also.
from dataselect import *
from openpyxl import Workbook
from tkinter import *
from tkinter import ttk, filedialog
root = Tk()
root.title("Select Data File")
# Actual File Selection based on Combobox Selection
def fileselect():
file_type = filetype.get()
if file_type == ".txt":
text = selecttxt()
textfile = filedialog.asksaveasfile(mode='w', defaultextension=".txt")
for line in text:
for number in line:
textfile.write(str(number)+" ")
textfile.write('\n')
elif file_type == ".xlsx":
excel = selectxlsx()
excelfile = filedialog.asksaveasfile(mode='w', defaultextension=".xlsx")
excelfilename = excelfile.name
excelbook = Workbook()
excelsheet = excelbook.active
rows = 0
for excel_row in excel:
cols = 0
for excel_cell in excel_row:
excelsheet.cell(row=rows, column=cols).value = excel[rows][cols]
cols += 1
rows += 1
excelbook.save(excelfilename)
def quit():
global root
root.destroy()
# Select the File Type to be opened (.txt or .xlsx for now)
ttk.Label(root, text="Please select the file type").grid(column=2, row=1)
filetype = StringVar()
sel_type = ttk.Combobox(root,values=('.txt','.xlsx'),textvariable=filetype)
sel_type.grid(column=2,row=2,sticky=E)
# Command Button for Opening File
cb_open = ttk.Button(root, text="Select File", command=fileselect)
cb_open.grid(column=2, row=3)
# Command Button for Quitting GUI
cb_quit = ttk.Button(root, text="Quit", command=quit)
cb_quit.grid(column=1, row=3)
root.mainloop()
There are two things you need to change:
1) Add sys.exit() to your quit method
def quit():
root.quit
root.destroy
sys.exit()
2) Add protocol to your root
root.protocol("WM_DELETE_WINDOW", quit)
Finally, don't forget to import sys.
I'm having issues with cx_freeze relative path logic on mac. I'm using python 3.3 and pyqt5 and building an app portable windows - mac.
The following simple script just loads an image into a QLabel as a QPixmap.
The code works fine both on windows and mac when launched from console, builds both on windows and mac.
The exe works on windows without any problem.
The app ( MacOSX ) does not load the image, same for the dmg.
I have a feeling it has something to do with relative path setting. The reason for this belief is the following:
- if I try to load the .app the image will not appear
- if I copy-paste the testimage.jpeg in the same folder where the .app is it will load the image.
I did try include_files in the setup with no results.
Can anyone help?
Here are the scripts:
First the file image_insert_test.py:
import sys
from PyQt5.QtWidgets import (QApplication, QDialog,
QErrorMessage, QLabel, QWidget, QVBoxLayout )
from PyQt5.QtCore import pyqtSlot, QDir, Qt
from PyQt5 import QtGui
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.fill_box2 = QLabel()
pixmap = QtGui.QPixmap('testimage.jpeg')
self.fill_box2.setPixmap(pixmap.scaled(100,100,Qt.KeepAspectRatio))
# set the layout
layout = QVBoxLayout()
layout.addWidget(self.fill_box2)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Window()
main.setWindowTitle('test gui')
main.show()
sys.exit(app.exec_())
the file setup.py:
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
options = {
'build_exe': {
"includes": ["matplotlib.backends.backend_macosx"] ,
"include_files" : ["testimage.jpeg"]
}
}
executables = [
Executable('image_insert_test.py', base=base)
]
setup(name='image_insert_test',
version='0.1',
description='Sample image_insert_test script',
options=options,
executables=executables
)
and this is the log of the cx_freeze bdist_mac http://pastebin.com/77uU4Exr
a workaround is the following:
instead of
pixmap = QtGui.QPixmap('testimage.jpeg')
place:
pixmap = QtGui.QPixmap(os.path.join(os.getcwd(),'image_insert_test-0.1.app/Contents/MacOS','testimage.jpeg')
this fishes the image path from the .app package but there has to be a more elegant way to do it.
When I minimize the application window on Windows XP and restore it later, the dock will be hidden. This has to do with view menu which has toggles to set visibility and of course is connected by signals.
I hope this will save someone a few hours of debugging.
Here is a full functional example with both wrong and right code:
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
class Ui_QMainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.resize(200, 200)
self.menubar = QtGui.QMenuBar(self)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 27))
self.menuMenu = QtGui.QMenu(self.menubar)
self.setMenuBar(self.menubar)
self.dock = QtGui.QDockWidget(self)
self.dock.setObjectName("dock")
self.dockContents = QtGui.QWidget()
self.dockContents.setObjectName("dockContents")
self.dock.setWidget(self.dockContents)
self.addDockWidget(QtCore.Qt.DockWidgetArea(4), self.dock)
self.action = QtGui.QAction(self)
self.action.setCheckable(True)
self.action.setChecked(True)
self.action.setObjectName("action")
self.menuMenu.addAction(self.action)
self.menubar.addAction(self.menuMenu.menuAction())
self.setWindowTitle("Example of dock remaining minimized")
self.menuMenu.setTitle("Menu")
self.dock.setWindowTitle("I'm a dock")
self.action.setText("Dock visibility")
if True:
# This is NOT working on Windows XP.
# Minimize the window and restore again, the dock is gone.
# Other than that it works.
QtCore.QObject.connect(self.action,
QtCore.SIGNAL("toggled(bool)"),
self.dock.setVisible)
QtCore.QObject.connect(self.dock,
QtCore.SIGNAL("visibilityChanged(bool)"),
self.action.setChecked)
else:
# This DOES work, but boy it looks nasty, writing useless
# per dock is not nice.
QtCore.QObject.connect(self.action,
QtCore.SIGNAL("triggered()"),
self.toggle_dock)
QtCore.QObject.connect(self.dock,
QtCore.SIGNAL("visibilityChanged(bool)"),
self.action.setChecked)
def toggle_dock(self):
self.dock.setVisible(not self.dock.isVisible())
def main():
app = QtGui.QApplication(sys.argv)
ui = Ui_QMainWindow()
ui.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
There is a much simpler way to do this, using QDock.toggleViewAction. This function returns a ready-made action that handles the checked state automatically.
So your code would become simply:
self.action = self.dock.toggleViewAction()
self.action.setObjectName("action")
self.menuMenu.addAction(self.action)
self.menubar.addAction(self.menuMenu.menuAction())
self.setWindowTitle("Example of dock remaining minimized")
self.menuMenu.setTitle("Menu")
self.dock.setWindowTitle("I'm a dock")
self.action.setText("Dock visibility")
and you can then get rid of all the signal handling.
I want to create a code which will display a window with a button, which clicked will create another window with some fields (like QLabel, QLineEdit, QSpinBox, etc.). However, I don't know how to create that popup window...
Here is my code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys # Needed for PySide
from PySide.QtCore import *
from PySide.QtGui import *
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
# Create widgets
self.label1 = QLabel("Label1")
self.button_open = QPushButton("Open popup")
self.button = QPushButton("Go!")
self.qbtn = QPushButton('Quit')
# Create layout and add widgets
layout = QVBoxLayout()
layout.addWidget(self.label1)
layout.addWidget(self.button_open)
# Buttons layout
hbox_buttons = QHBoxLayout()
hbox_buttons.addStretch(1)
hbox_buttons.addWidget(self.button)
hbox_buttons.addWidget(self.qbtn)
# Main layout
layout.addStretch(1)
layout.addWidget(self.button_open)
layout.addLayout(hbox_buttons)
self.setLayout(layout)
# Add buttons slots
self.button_open.clicked.connect(self.popup)
self.button.clicked.connect(self.function_runner)
self.qbtn.clicked.connect(QCoreApplication.instance().quit)
def popup (self, parent=__init__):
new_win = # I wonder what should be here
if __name__ == '__main__':
# Create the Qt Application
app = QApplication(sys.argv)
# Create and show the form
form = Form()
form.show()
# Run the main Qt loop
sys.exit(app.exec_())
I don't know if this is the best way, but the one I could figure out over the night... I hope it will help someone who got stuck with a similar problem.
So, I (simply) created a separate code for that second window and called it with
from subprocess import call
call("./my_2nd_window_code.py")