PyQt5 - Clicking Cancel on QFileDialog Closes Application - python

I've noticed that, using the following code, if you choose to click "Cancel" on the FileDialog for "Import File", the entire application closes instead of returning to the menu and awaiting a different choice. How can I get it to just return to the mainMenu?
(Note: I've noticed if I don't put anything after the initial file dialog call, it functions fine.)
Code:
import sys
import xml.etree.ElementTree as et
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class MainMenu(QDialog):
def __init__(self):
QDialog.__init__(self)
layout = QGridLayout()
# Create Objects for Main Menu
logoLabel = QLabel("TESTAPP")
logoFont = QFont("Broadway", 48)
logoLabel.setFont(logoFont)
versionLabel = QLabel("Version 0.1a")
copyrightLabel = QLabel("Copyright 2016")
importButton = QPushButton("Import File")
quitButton = QPushButton("Quit")
# Set Locations of Widgets
layout.addWidget(logoLabel, 0, 0)
layout.addWidget(versionLabel, 1, 0)
layout.addWidget(copyrightLabel, 2, 0)
layout.addWidget(importButton, 4, 0)
layout.addWidget(quitButton, 5, 0)
self.setLayout(layout)
self.setWindowTitle("NESSQL")
# Connect Buttons to Actions
importButton.clicked.connect(self.importFile)
quitButton.clicked.connect(self.close)
def importFile(self):
# Open dialog box to get the filename
file = QFileDialog.getOpenFileName(self, caption="File to Import", directory=".",
filter="All Files (*.*)")
data = et.parse(file)
root = data.getroot()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainMenu = MainMenu()
mainMenu.show()
app.exec_()

by keeping condition for checking whether file is empty or not you can avoid this issue.
It goes something like this in your case.
def importFile(self):
# Open dialog box to get the filename
file = QFileDialog.getOpenFileName(self, caption="File to Import",
directory=".",filter="All Files (*.*)")
if not file[0] == "":
data = et.parse(file)
root = data.getroot()

saran vaddi's answer didn't work for me but this did:
def importFile(self):
# Open dialog box to get the filename
file = QFileDialog.getOpenFileName(self, caption="File to Import", directory=".", filter="All Files (*.*)")
# If file is blank, simply return control to calling function
if not file:
return

Related

When I try to browse for a .xslx file a new Excel document opens

I'm currently working on a GUI with PyQt5.
I am using the menu bar to load a file, when i click it the program calls this function:
def getxlsbase(self):
filePath_base, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Select file', './', 'Excel Files (*.xls *.xlsx)')
base = xlrd.open_workbook(filePath_base)
hoja_base = base.sheet_by_index(0)
num_row = hoja_base.nrows
num_col = hoja_base.ncols
When the browse window opens and I select the file, a blank Excel document opens, how can I avoid this?
EDIT:
I tried this method but I still have this issue, it only happens with excel docs. I am using Spyder3
from tkinter import *
from tkinter import filedialog
root = Tk()
root.withdraw()
filepath = filedialog.askopenfilename()
print(filepath)
I don't know if I understood the question correctly, but if, like me, when you open an excel document, a window opens with a file selection, then you can do this:
def get_path_excel_file(self):
excel_path, _ = QFileDialog.getOpenFileName(self,
'Select file',
'./',
'Excel Files (*.xls *.xlsx)')
# assign a path to some element
self.label_5.setText(f"{excel_path}")
# we get the path from this element
book = openpyxl.load_workbook(fr"{self.label_5.text()}")
The method you provided works correctly.
import sys
import xlrd
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import QAxWidget
class AxWidget(QWidget):
def __init__(self, *args, **kwargs):
super(AxWidget, self).__init__(*args, **kwargs)
self.resize(800, 600)
layout = QVBoxLayout(self)
self.axWidget = QAxWidget(self)
layout.addWidget(self.axWidget)
layout.addWidget(QPushButton('Select file', self, clicked=self.getxlsbase))
def getxlsbase(self):
filePath_base, _ = QFileDialog.getOpenFileName(self,
'Select file',
'./',
'Excel Files (*.xls *.xlsx)')
print("filePath_base->", filePath_base)
base = xlrd.open_workbook(filePath_base)
print("base->", base)
hoja_base = base.sheet_by_index(0)
print("hoja_base->", hoja_base)
num_row = hoja_base.nrows
print("num_row->", num_row)
num_col = hoja_base.ncols
print("num_col->", num_col)
return self.openOffice(filePath_base, 'Excel.Application')
def openOffice(self, path, app):
self.axWidget.clear()
if not self.axWidget.setControl(app):
return QMessageBox.critical(self, 'Error', 'No installation %s' % app)
self.axWidget.dynamicCall(
'SetVisible (bool Visible)', 'false')
self.axWidget.setProperty('DisplayAlerts', False)
self.axWidget.setControl(path)
def closeEvent(self, event):
self.axWidget.close()
self.axWidget.clear()
self.layout().removeWidget(self.axWidget)
del self.axWidget
super(AxWidget, self).closeEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = AxWidget()
ex.show()
sys.exit(app.exec_())

PyQt: How convert my script to GUI?

I'm following this tutorial for a PyQt5 GUI window:
Here's My code on pastebin.
import sys
from PyQt5 import QtWidgets, QtGui
def window1():
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
b = QtWidgets.QPushButton('Comparison Report', w)
l1 = QtWidgets.QLabel(w)
l2 = QtWidgets.QLabel(w)
l1.setText('Main Page')
b.setGeometry(200, 100, 300, 70)
w.setWindowTitle('Diff Util')
w.setGeometry(800, 200, 720, 800)
l1.move(310, 5)
w.show()
sys.exit(app.exec_())
#import file_report
#def on_click(self):
#file_report()
window1()
Here's a comparison file script also on pastebin... but i Need 10rep to link it >_>
import sys
import os
import difflib
first_file = input("Select original file: ")
second_file = input("Select second file for comparison: ")
first_file_lines = open(first_file).readlines()
second_file_lines = open(second_file).readlines()
difference = difflib.HtmlDiff(tabsize=8,
wrapcolumn=100).make_file(first_file_lines, second_file_lines, first_file, second_file, charset='utf-8')
difference_report = open('difference_report.html', 'w')
difference_report.write(difference)
difference_report.close()
os.startfile('difference_report.html')
My question is, how to connect my file_report.py to the pushbutton I've created with PyQt5?
As you can see I commented out "import file_report" because from my understanding I'm supposed to import my script... but the import causes it to run the script in terminal, and after execution will open my GUI. I would like to run this script, but contain it within the GUI window I've created instead of opening a terminal for execution.
So where in the PyQt5 script should I import, and include the .py file?
GUIs are not friendly with blocking tasks since for their existence they create a loop. Therefore the function input() should not be used, the solution to use elements provided by the library as QLineEdit, PyQt also provides dialog boxes for the selection of files.
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
import difflib
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.setLayout(QtWidgets.QGridLayout())
self.le1 = QtWidgets.QLineEdit("", self)
self.le2 = QtWidgets.QLineEdit("", self)
self.le3 = QtWidgets.QLineEdit("", self)
self.btn1 = QtWidgets.QPushButton("Select first file")
self.btn2 = QtWidgets.QPushButton("Select second file")
self.btn3 = QtWidgets.QPushButton("Select save File")
self.btnRun = QtWidgets.QPushButton("Run")
self.layout().addWidget(self.le1, 1, 1)
self.layout().addWidget(self.le2, 2, 1)
self.layout().addWidget(self.le3, 3, 1)
self.layout().addWidget(self.btn1, 1, 2)
self.layout().addWidget(self.btn2, 2, 2)
self.layout().addWidget(self.btn3, 3, 2)
self.layout().addWidget(self.btnRun, 4, 2)
self.btnRun.clicked.connect(self.onRun)
self.btn1.clicked.connect(self.selectFirstFile)
self.btn2.clicked.connect(self.selectSecondFile)
self.btn3.clicked.connect(self.selectSaveFile)
def selectFirstFile(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select Files", QtCore.QDir.currentPath(), "*.html")
if filename != "":
self.le1.setText(filename)
def selectSecondFile(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select Files", QtCore.QDir.currentPath(), "*.html")
if filename != "":
self.le2.setText(filename)
def selectSaveFile(self):
filename, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Select Files", QtCore.QDir.currentPath(), "*.html")
if filename != "":
self.le3.setText(filename)
def onRun(self):
first_file = self.le1.text()
second_file = self.le2.text()
output_file = self.le3.text()
first_file_lines = open(first_file).readlines()
second_file_lines = open(second_file).readlines()
difference = difflib.HtmlDiff(tabsize=8, wrapcolumn=100).make_file(first_file_lines, second_file_lines, first_file, second_file, charset='utf-8')
difference_report = open(output_file, 'w')
difference_report.write(difference)
difference_report.close()
QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(output_file))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

PyQt5: how do I use a variable output from one button for another button?

I am trying to implement a GUI on a python code using PyQt5. I figured out how to use buttons and how to connect them to functions.
Button b3 calls the function "SelectFile"
self.b3.clicked.connect(self.SelectFile)
def SelectFile(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
filename = QFileDialog.getOpenFileName(self, "Select file", "", "TMY3 files (*.epw)", options=options)[0]
print(filename)
return filename
The problem I have is that I want "SelectFile" to return the path of a file, and then use that path for another function called by another button. How can I do that?
For example,
self.b1.clicked.connect(self.btn_clk)
def btn_clk(self):
sender = self.sender()
if sender.text() =='Print':
test = filename
print(test)
"filename" is not passed to "btn_clk" and I don't know how to do that.
I tried to input "filename" in the definition of "btn_clk" and other attempts as well, but nothing worked.
Thanks
def SelectFile(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
filename = QFileDialog.getOpenFileName(self, "Select file", "", "TMY3 files (*.epw)", options=options)[0]
print(filename)
self.b1_filename = filename
return filename
self.b1.clicked.connect(self.btn_clk)
def btn_clk(self):
sender = self.sender()
if sender.text() =='Print':
test = self.b1_filename
print(test)
Just store it in the class, and it's ready to go. Use the code below to test. You can adjust to suit with your code.
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys
class TestSelectFile(QDialog):
def __init__(self):
QDialog.__init__(self)
self.layout = QVBoxLayout()
self.selectfilebutton = QPushButton('Select file')
self.printpathbutton = QPushButton('Press to print')
self.setLayout(self.layout)
self.layout.addWidget(self.selectfilebutton)
self.layout.addWidget(self.printpathbutton)
self.selectfilebutton.clicked.connect(self.getpath)
self.printpathbutton.clicked.connect(self.printpath)
def getpath(self):
self.path = QFileDialog.getOpenFileName(self,caption='Get a path from',filter='All Files(*.*)')
def printpath(self):
print(self.path)
app = QApplication(sys.argv)
dialog = TestSelectFile()
dialog.show()
app.exec_()

PyQt4: Save a QListWidget

I'm new in PyQt4.
I have a QListWidget, and then i would like to saveit directly but the only example i find is a a textedit and need to open a file first.
But in my case there is no file to open.
is it possible to do it?
so far my code looks like this:
def initUI(self):
self.edit = QtGui.QListWidget()
btn1 = QtGui.QPushButton("Check")
btn2 = QtGui.QPushButton("Quit")
btn1.clicked.connect(self.buttonClicked)
btn2.clicked.connect(self.closeEvent)
toolBar = QtGui.QToolBar()
fileButton = QtGui.QToolButton()
fileButton.setText('File')
fileButton.setMenu(self.menu())
saveButton = QtGui.QToolButton()
saveButton .setText('save')
saveButton .clicked.connect(self.save_menu)
toolBar.addWidget(fileButton)
toolBar.addWidget(saveButton )
def save_menu(self):
fn = QtGui.QFileDialog.getSaveFileName(self, "Save as...", '.',
"ODF files (*.odt);;HTML-Files (*.htm *.html);;All Files (*)")
self.setCurrentFileName(fn)
return self.fileSave()
Assuming you just want to save the text entries in your list, this should work. Beware that it will try and write a file to your disk.
import sys
import os
from PyQt4 import QtGui
class AnExample(QtGui.QMainWindow):
def __init__(self):
super(AnExample, self).__init__()
self.buildUi()
def buildUi(self):
self.listWidget = QtGui.QListWidget()
self.listWidget.addItems(['one',
'two',
'three'])
warning = QtGui.QLabel("Warning, this progam can write to disk!")
saveButton = QtGui.QPushButton('Save to location...')
justSaveButton = QtGui.QPushButton('Just save!')
saveButton.clicked.connect(self.onSave)
justSaveButton.clicked.connect(self.onJustSave)
grid = QtGui.QGridLayout()
grid.addWidget(warning, 0, 0)
grid.addWidget(self.listWidget, 1, 0)
grid.addWidget(saveButton, 2, 0)
grid.addWidget(justSaveButton, 3, 0)
central = QtGui.QWidget()
central.setLayout(grid)
self.setCentralWidget(central)
def onSave(self):
self.saveFile(True)
def onJustSave(self):
self.saveFile(False)
def saveFile(self, showDialog):
"""
Function that will save list items to file.
"""
# save to TESTING.txt in current working directory
savePath = os.path.join(os.getcwd(),
'TESTING.txt')
# allow user to override location if requested
if showDialog:
savePath = QtGui.QFileDialog.getSaveFileName(self,
'Save text file',
savePath,
'TESTING.txt')
# if just saving, or user didn't cancel, make and save file
if len(savePath) > 0:
with open(savePath, 'w') as theFile:
for i in xrange(self.listWidget.count()):
theFile.write(''.join([str(self.listWidget.item(i).text()),
'\n']))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = AnExample()
ex.show()
sys.exit(app.exec_())

How to refresh/replace gtk.ToolItemGroup

I wrote this code, it's supposed to be a clipart browser (locked to "klip" folder under current directory).
When I start add signal at folder button (dbutton) I screw up: I don't know how to refresh the toolitemgroup content and icons keep appended, I can't remove manually since the button generated in loop.
And one more, how can I "auto-fit/trim" the button label? Cause it grows insane if the filename is lengthy.
import gtk
from os.path import join,normpath,splitext, isdir
from os import getcwd, walk, mkdir
klip="klip"
klipdir=join(getcwd(),klip)
#init dir
if not isdir(klipdir):
mkdir(klipdir)
class kaosmu:
def icon_builder_cb(self, widget, data=klip):
if data != klip:
homebutton = gtk.ToolButton(gtk.STOCK_HOME)
browser.add(homebutton)
upbutton = gtk.ToolButton(gtk.STOCK_GO_UP)
browser.add(upbutton)
#folder
idx=dirs.index(data)
print idx
for i in dirs[idx+1]:
dbutton = gtk.ToolButton(gtk.STOCK_OPEN)
dbutton.set_label(i)
dbutton.connect("clicked", self.icon_builder_cb, join(data,i))
browser.add(dbutton)
#files
for i in dirs[idx+2]:
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(data,i),32,32)
img=gtk.Image()
img.set_from_pixbuf(pixbuf)
svg = gtk.ToolButton(img,splitext(i)[0])
browser.add(svg)
browser.show_all()
def im_browser_cb(self, widget, data=klipdir):
global dirs
dirs = []
for (p, d, f) in walk(data):
key=p[len(data)-len(klip):]
dirs.append(key)
dirs.append(d)
dirs.append(f)
def __init__(self):
self.im_browser_cb(None)
window = gtk.Window()
window.set_default_size(1024, 800)
window.set_border_width(2)
window.connect("destroy", lambda w: gtk.main_quit())
drawingarea = gtk.DrawingArea()
drawingarea.set_size_request(600, 700)
hpane = gtk.HPaned()
menuscroll = gtk.ScrolledWindow()
canvasscroll = gtk.ScrolledWindow()
toolpalette = gtk.ToolPalette()
toolpalette.set_style(gtk.TOOLBAR_BOTH)
toolpalette.set_icon_size(gtk.ICON_SIZE_DND)
hpane.set_position(250)
window.add(hpane)
hpane.add1(menuscroll)
hpane.add2(canvasscroll)
menuscroll.add_with_viewport(toolpalette)
canvasscroll.add_with_viewport(drawingarea)
global browser
browser = gtk.ToolItemGroup(" Browser ")
toolpalette.add(browser)
toolpalette.set_expand(browser, True)
self.icon_builder_cb(None)
window.show_all()
def main(self):
gtk.main()
if __name__ == "__main__":
kaos = kaosmu()
kaos.main()
I solved this with:
while browser.get_nth_item(0):
browser.remove(browser.get_nth_item(0))

Categories