Opening files with pyqt application - python

I want my pyqt application to act as a file handler for a certain file format (with a certain suffix), that is,
I want to be able to open files from the operating system directly in my pyqt application, say by double clicking or contextual menu "open with".
Is this possible?
Thank you and best regards!

Yes, it is possible. I suggest using the
QFileDialog.getOpenFileName()
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFileDialog
class MainWin(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(150,150,200,150)
self.setWindowTitle("Test")
button = QPushButton('Open with', self)
button.clicked.connect(self.dialog)
button.resize(100,32)
button.move(50,50)
self.show()
def dialog(self):
# https://doc.qt.io/qtforpython-5/PySide2/QtWidgets/QFileDialog.html#PySide2.QtWidgets.PySide2.QtWidgets.QFileDialog.getOpenFileName
file, check = QFileDialog.getOpenFileName(
None,
"QFileDialog.getOpenFileName()",
"",
self.tr(
'All Files (*);;'
'Python Files (*.py);;'
'Text Files (*.txt)'))
if check:
print(file)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MainWin()
sys.exit( app.exec_() )

Related

PyQt5 QFileDialog - Highlight Suggested File in the QListView Widget

I’m using PyQt5 on a Windows platform. I want to present a QFileDialog to the user with the suggested file highlighted in both the QListView and the QLineEdit widgets within the QFileDialog window. The selectFile() method adds the filename to the QLineEdit widget and highlightss it, but does not highlight the file in the QListView widget.
I tried the suggestion in How to setFocus() on QListView in QFileDialog in PyQt5?, but I could not see that the QListView had focus and could not highlight a file with selectFile().
In QFileDialog, is there a way to highlight the filename in the QistView and in the QLineEdit widgets? If not, is there a way to highlight the filename in just the QListView?
Here is a minimalized script that shows the filename highlighted in the QLineEdit widget.
import sys
from PyQt5.QtWidgets import QApplication, QFileDialog
from PyQt5.QtCore import QDir
class MyClass(QFileDialog):
def __init__(self):
super().__init__()
self.DontUseNativeDialog
self.openFile()
def openFile(self):
qdir = QDir()
qdir.setPath('C:\\Users\\Slalo\\Documents\\VideoGates\\PVRTop\\Folder')
qdir.setSorting(QDir.Name | QDir.Reversed)
qdirlist = qdir.entryList()
self.setWindowTitle('Open File')
self.setDirectory(qdir)
self.setNameFilter('All(*.*)')
self.selectFile(qdirlist[1])
if self.exec():
fname = self.selectedFiles()
print(fname)
if __name__ == '__main__':
app = QApplication(sys.argv)
dlg = MyClass()
sys.exit(app.exec())
After testing #musicamante 's patience, here is the solution. The QFileDialog window looks a little different than the native Windows dialog, but that's OK - it works as intended. Here is the corrected script.
import sys, os
from PyQt5.QtWidgets import QApplication, QFileDialog
class MyClass(QFileDialog):
def __init__(self):
super().__init__()
self.setOption(QFileDialog.DontUseNativeDialog)
self.openFile()
def openFile(self):
dirname = 'C:\\Users\\Slalo\\Documents\\VideoGates\\PVRTop\\Folder'
fileList = os.listdir(dirname)
self.setWindowTitle('Open File')
self.setDirectory(dirname)
self.setNameFilter('All(*.*)')
self.selectFile(fileList[1])
if self.exec():
fname = self.selectedFiles()
print(fname)
if __name__ == '__main__':
app = QApplication(sys.argv)
dlg = MyClass()
sys.exit(app.exec())

PyQt - Open file dialog from a background thread

From my main GUI, the user can click a button to select a script (another Python file), via a file dialog, to run in a background thread. The script then has to get the user to select another file.
Since the script is running in a separate thread to the main GUI, how can I get it to open a file dialog and get the result? An example is shown below - the print() shows where I'd like to open the file dialog.
Also, the script the user chooses knows nothing about the existing GUI format/setup, etc. So, it would be useful if I could somehow run a new 'instance' of PyQt from the script to open a dialog. Or, failing that, pass in some reference to the GUI that the script can use (but I know it can't be run from a different thread).
import threading
import sys
from PySide2.QtWidgets import QWidget, QVBoxLayout, QTextEdit, QPushButton, QApplication, QFileDialog
from PySide2 import QtCore
class TextEditDemo(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("TEST")
self.resize(600,540)
self.textEdit = QTextEdit()
self.btnPress1 = QPushButton("Run")
layout = QVBoxLayout()
layout.addWidget(self.textEdit)
layout.addWidget(self.btnPress1)
self.setLayout(layout)
self.btnPress1.clicked.connect(self.btnPress1_Clicked)
def btnPress1_Clicked(self):
script_pth = self.getFileName()
threading.Thread(target=run_script_in_bg, args=(script_pth,)).start()
def getFileName(self):
response = QFileDialog.getOpenFileNames(
parent=self
)
return response[0]
def run_script_in_bg(script_pth):
# Assume this opens and runs script_pth
# and that script needs to get user to choose another file
print(f"{script_pth} is running. Now it needs to open file dialog and get result")
def main():
app = QApplication(sys.argv)
win = TextEditDemo()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

PyQt5 File open Dialog

is there any way to open a folder with pyqt5 file dialog
I tried taking the quotes, I want to open a folder or a directory with subdirectories or subfolders
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFileDialog, QTextEdit, QPushButton, QLabel, QVBoxLayout
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 600)
self.button1 = QPushButton('Open Project Folder')
self.button1.clicked.connect(self.get_folder)
self.labelImage = QLabel()
self.textEditor = QTextEdit()
layout = QVBoxLayout()
layout.addWidget(self.button1)
layout.addWidget(self.labelImage)
layout.addWidget(self.button2)
layout.addWidget(self.textEditor)
self.setLayout(layout)
def get_folder(self):
file_name, _ = QFileDialog.getOpenFileName(
self, 'Project Data', r"", "")
print(file_name)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())```
There are various static functions available for QFileDialog, if you need to open a directory, don't use getOpenFileName but getExistingDirectory().
As you can see from the documentation, the arguments are slightly different, and
if you run help(QtWidgets.QFileDialog.getExistingDirectory) from the python shell, you'll see the full argument signature and the returned value written in the python syntax.
getExistingDirectory(parent: QWidget = None, caption: str = '', directory: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = QFileDialog.ShowDirsOnly) -> str
The last part ( -> str) means that there is only one returned value, which is the string of the selected directory (which will be empty if the user cancels the dialog).
def get_folder(self):
folder = QFileDialog.getExistingDirectory(
self, 'Project Data', '')
if folder:
print(folder)
I suggest you to always study the documentation of each class you're using, and using the official documentation; even if it's C++ oriented, the functions have the same names on PyQt, and their arguments/returned values are the same in 99% of the cases. Whenever you've a doubt or you face a problem about wrong arguments or returned data, you can check the official PyQt documentation or just use help(class.function) in the python shell.

QFileDialog always opens behind main window

I'm trying to open a file in my PySide2 application, but the file dialog always opens below the main window and appears as another application in the launcher. The application's name is "Portal".
I see other answers where the solution is to pass the main window as the first parameter to getOpenFileName(), but that doesn't work for me.
Here's a simple demonstration of the problem:
import sys
from PySide2.QtWidgets import QPushButton, QFileDialog, QApplication
class DemoButton(QPushButton):
def __init__(self, text):
super().__init__(text)
self.clicked.connect(self.on_click)
def on_click(self):
file_name, _ = QFileDialog.getOpenFileName(
self,
"Open a text file.",
filter='Text file (*.txt)')
print(file_name)
def main():
app = QApplication(sys.argv)
button = DemoButton("Hello World")
button.show()
app.exec_()
sys.exit()
main()
I thought maybe the parent had to be a QMainWindow, so I tried that:
import sys
from PySide2 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
main_widget = QtWidgets.QWidget(self)
self.setCentralWidget(main_widget)
# layout initialize
g_layout = QtWidgets.QVBoxLayout()
layout = QtWidgets.QFormLayout()
main_widget.setLayout(g_layout)
# Add Widgets
self.exec_btn = QtWidgets.QPushButton('Execute')
self.exec_btn.clicked.connect(self.find_file)
# global layout setting
g_layout.addLayout(layout)
g_layout.addWidget(self.exec_btn)
def find_file(self):
file_name, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
"Open a text file.",
filter='Text file (*.txt)')
print(file_name)
def main():
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
sys.exit()
main()
The file dialog behaved exactly the same.
I'm using PySide2 5.12.2, Python 3.6.7, and running on Ubuntu 18.04.
Thanks to ekhumoro's comment, I learned that I can tell PySide2 not to use the native file dialog.
import sys
from PySide2.QtWidgets import QPushButton, QFileDialog, QApplication
class DemoButton(QPushButton):
def __init__(self, text):
super().__init__(text)
self.clicked.connect(self.on_click)
def on_click(self):
file_name, _ = QFileDialog.getOpenFileName(
self,
"Open a text file.",
filter='Text file (*.txt)',
options=QFileDialog.DontUseNativeDialog)
print(file_name)
def main():
app = QApplication(sys.argv)
button = DemoButton("Hello World")
button.show()
app.exec_()
sys.exit()
main()
That fixes the behaviour by bringing the file dialog to the front, but I think the native file dialog looks better. Hopefully, there's another option that can make the native file dialog work properly.

PyQt: best way to do the trick "start at boot" for my program in Windows

I'm using PyQt to develop an application that in Windows, if set in preferences, should be able to start at boot.
I'm releasing this software with PyInstaller as a single executable file; i don't have a proper "installer".
Which is the best way to achieve this? ( = starting at boot)
A possible solution is to add a link in the startup folder, but i have to do it from the software: it's possible? Other ways?
There is an universal path to the Startup folder? Can i have some rights' problem?
try this code (it works for me with py2exe):
import sys
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import (QApplication, QWidget, QCheckBox, QPushButton,
QVBoxLayout)
RUN_PATH = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
class MainWidget(QWidget):
def __init__(self,parent=None):
super(MainWidget, self).__init__(parent)
self.settings = QSettings(RUN_PATH, QSettings.NativeFormat)
self.setupUi()
# Check if value exists in registry
self.checkbox.setChecked(self.settings.contains("MainWidget"))
def setupUi(self):
self.checkbox = QCheckBox("Boot at Startup", self)
button = QPushButton("Close", self)
button.clicked.connect(self.close)
layout = QVBoxLayout(self)
layout.addWidget(self.checkbox)
layout.addWidget(button)
def closeEvent(self, event):
if self.checkbox.isChecked():
self.settings.setValue("MainWidget",sys.argv[0]);
else:
self.settings.remove("MainWidget");
event.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWidget()
w.show()
app.exec_()
You may add registry key under [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run], with any name and value "path_to_your_exec". this will require local administrator right, but will work for all users.
The same key but starting with [HKEY_CURRENT_USER] will not require administrator privileges, but will work only for current user.
That registry path is the same for win2k..win7

Categories

Resources