Why python not show in path icon? - python

I wrote below code
import sys,time
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
app = QApplication(sys.argv)
sys.path.append(r"C:\Users\hpaalm\Desktop")
a=QPushButton()
a.setIcon(QIcon('1.png'))
a.show()
app.exec_()
when i run it in IDE, it show my icon, but when run it in CMD it not show icon. what is problem?
python C:\Users\hpaalm\Desktop\a.py

sys.path contains a list of paths where python imports the modules, this does not serve to import files, icons or similar resources. Instead it is best to create a function that binds the directory path with the filename and return the full path of the icon:
import os
import sys
from PyQt5 import QtGui, QtWidgets
ICON_DIR = r"C:\Users\hpaalm\Desktop"
def get_path_icon(filename):
return os.path.join(ICON_DIR, filename)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
a = QtWidgets.QPushButton()
a.setIcon(QtGui.QIcon(get_path_icon('1.png')))
a.show()
sys.exit(app.exec_())

Related

Save .xlsx file from st.download_button (Streamlit) using PySide6

I created a dashboard with Streamlit as a standalone application with the PySide6 library, however, I need to download a file generated in Streamlit through a button (st.download_button), but when it is clicked, nothing happens. Could you help on how to download Streamlit files with PySide6?
Here's my code:
app.py (PySide6 connector)
import atexit
import subprocess as sp
import os
from PySide6 import QtCore, QtWebEngineWidgets, QtWidgets
from PySide6.QtGui import QIcon
def kill_server(s):
if os.name == 'nt':
sp.call(['taskkill', '/F', '/T', '/PID', str(s.pid)])
elif os.name == 'posix':
s.taskkill()
else:
pass
if __name__ == '__main__':
cmd = f'streamlit run rpbr.py --server.headless=True'
p = sp.Popen(cmd.split(), stdout=sp.DEVNULL)
atexit.register(kill_server, p)
hostname = 'localhost'
port = 8501
app = QtWidgets.QApplication()
my_icon = QIcon()
my_icon.addFile('app.ico')
app.setWindowIcon(my_icon)
view = QtWebEngineWidgets.QWebEngineView()
view.setWindowTitle("Plataform")
view.load(QtCore.QUrl(f'http://{hostname}:{port}'))
view.show()
app.exec()
rpbr.py (Streamlit - code area with download button)
run = st.download_button(label="Download", data=stats_rpbr(typ, pa, fab, brand, apr, start, end),
file_name='Statistics.xlsx')
I tried to find solutions by flagging the file download directly in PySide6, but nothing.

PySide6 + Qt Creator, pysideplugin error results in gray screen

Every time I create a Window UI - Dynamic load project in Qt Creator v8.0.2 and run the project I get the following error:
error: qt.pysideplugin: Environment variable PYSIDE_DESIGNER_PLUGINS
is not set, bailing out.
As a result, the window doesn't display any widgets, it is just a gray empty window
I have tried to configure os.environ['PYSIDE_DESIGNER_PLUGINS'] = '.' but then I get the following error:
error: qt.pysideplugin: No python files found in '.'.
Is there a way to load the pysideplugin to Qt Creator v8.0.2 or to remove the errors related to it and make the project run and show the widgets?
I am testing with a very simple UI
But when I run the project I can only see the following:
The complete code in the mainwindow.py file is:
# This Python file uses the following encoding: utf-8
import os
from pathlib import Path
import sys
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtCore import QFile
from PySide6.QtUiTools import QUiLoader
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.load_ui()
def load_ui(self):
loader = QUiLoader()
path = Path(__file__).resolve().parent / "form.ui"
ui_file = QFile(path)
ui_file.open(QFile.ReadOnly)
loader.load(ui_file, self)
ui_file.close()
if __name__ == "__main__":
#os.environ['PYSIDE_DESIGNER_PLUGINS']='.'
app = QApplication(sys.argv)
widget = MainWindow()
widget.show()
sys.exit(app.exec())
I am using python 3.10.5 and PySide6 version 6.4.0.1

Why my local html is not accessed when I load it into PySide6 QWebEngineView?

I was learning Qt6, and I wrote a demo putting a local html file into it to test the QWebEngineView Widget. However, the web page shows the info:
Your file counldn't be accessed
It may have been moved, edited, or deleted.
ERR_FILE_NOT_FOUND
Here is my test.py source code:
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout)
from PySide6 import QtCore
from PySide6.QtWebEngineWidgets import QWebEngineView
class webView(QWidget):
def __init__(self):
super(webView, self).__init__()
self.layout = QVBoxLayout(self)
self.webV = QWebEngineView()
self.fileDir = QtCore.QFileInfo("./docs.html").absoluteFilePath()
print(self.fileDir)
self.webV.load(QtCore.QUrl("file:///" + self.fileDir))
self.layout.addWidget(self.webV)
if __name__ == "__main__":
app = QApplication([])
web = webView()
web.show()
sys.exit(app.exec())
In Addition, the docs.html has been put into the same directory as the test.py file. And when I print the web.fileDir, the result is correct.
You are hardcoded the url and the path may be wrong, in these cases the url is better step by step. I assume that the html is next to the .py then the solution is:
import os
from pathlib import Path
import sys
from PySide6.QtCore import QUrl
from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget
from PySide6.QtWebEngineWidgets import QWebEngineView
CURRENT_DIRECTORY = Path(__file__).resolve().parent
class webView(QWidget):
def __init__(self):
super(webView, self).__init__()
filename = os.fspath(CURRENT_DIRECTORY / "docs.html")
url = QUrl.fromLocalFile(filename)
self.webV = QWebEngineView()
self.webV.load(url)
layout = QVBoxLayout(self)
layout.addWidget(self.webV)
if __name__ == "__main__":
app = QApplication([])
web = webView()
web.show()
sys.exit(app.exec())
In Qt in general is strongly preferred to use the qrc files, and the Qt resource management system. Here: Can QWebView load images from Qt resource files? is a small yet, neat example of something that is similar to your problem. You may also view the official PySide6 resource usage :
https://doc.qt.io/qtforpython/tutorials/basictutorial/qrcfiles.html

how to use a promoted class in PyQt5?

in principal I reopen my question some days ago:
where-do-i-write-the-class-for-a-single-promoted-qwidget-from-qt-designer
The solution works, but I run into 2 more questions
if I want to change the text in the class neuLabel, how do i adress the class out of main program?
Additional information for minimal example as required:
I have a qt designer main window, named testpromote.ui. It contains only one label. Text is "MyLabel", the name is neuLabel and it is promoted as neulabel.
I need 2 .py files in one directory.
First the main testpromote.py
import sys
import os
from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import * #QPainter
import neulabel
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
uifile_1 = os.path.join(CURRENT_DIR, "testpromote.ui")
form_1, base_1 = uic.loadUiType(uifile_1)
class myApp(base_1, form_1):
def __init__(self):
super(base_1,self).__init__()
self.setupUi(self)
# ??????????????
#neuLabel.setText(neuLabel,"from main")
# ??????????????
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = myApp() #Dialog()
ex.show()
sys.exit(app.exec_())
2nd file is neulabel.py
from PyQt5.QtWidgets import *
from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import * #QPainter
class neuLabel(QLabel):
def __init__(self,parent=None):
super().__init__(parent)
self.setAcceptDrops(True)
self.setText("from code")
print("the new pixmap?", self.text())
My aim is to change the text of the label out of the main program testpromote.py
I do not understand, how to import the neulabel.py, so that i could change the text of the label.I tried it with "neuLabel.setText(neuLabel,"from main")", but this doesn't work. I tried it with other code too, but not succesfully. (This is marked within the # ????????? lines)
To see, if the text in the label changes, I added in neulabel.py the
self.setText() statement, but the text does not change in the window.
(i hope, it is clearer now)

PyQt5 to PySide2, loading UI-Files in different classes

I have a python application which runs under python3.6 and is using PyQt5 for loading Ui windows. These windows were created with Qt Designer 5.9.4. The Code below shows a working example with PyQt5.
Now i want to have exactly the same functionality but with PySide2. For now, I couldn't work out how to load an Ui File and use its objects (buttons, tables etc.) in a separate class. For example: by clicking a button in the first window/class, a second window apears which functions are defined in a separate class, see example. All examples that I found, just load an Ui-Window but don't show how to work with it. Can anyone help?
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from PyQt5.uic import loadUiType
from PyQt5 import QtGui, QtCore
Ui_FirstWindow, QFirstWindow = loadUiType('first_window.ui')
Ui_SecondWindow, QSecondWindow = loadUiType('second_window.ui')
class First(Ui_FirstWindow, QFirstWindow):
def __init__(self):
super(First, self).__init__()
self.setupUi(self)
self.button.clicked.connect(self.show_second_window)
def show_second_window(self):
self.Second = Second()
self.Second.show()
class Second(Ui_SecondWindow, QSecondWindow):
def __init__(self):
super(Second, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
PySide does not offer these methods, but one solution is to modify the source code of the PyQt uic module by changing the imports from PyQt5 to PySide2, for legal terms do not modify the license, in addition to the code that will keep the PyQt licenses.
To do this, download the source code from the following link and unzip it.
And execute the following script:
convert_pyqt5_to_pyside2.py
import os
import fileinput
import argparse
import shutil
def modify_source_code(directory, text_to_search, replacement_text):
for path, subdirs, files in os.walk(directory):
for name in files:
filename = os.path.join(path, name)
with fileinput.FileInput(filename, inplace=True) as file:
for line in file:
if line.startswith('#'):
# not change on comments
print(line, end='')
else:
print(line.replace(text_to_search, replacement_text), end='')
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", help="Input directory")
parser.add_argument("-o", "--output", help="Output directory")
args = parser.parse_args()
if args.input and args.output:
input_dir = os.path.join(os.path.abspath(args.input), "pyuic", "uic")
output_dir = os.path.abspath(args.output)
shutil.copytree(input_dir, output_dir)
modify_source_code(output_dir, 'PyQt5', 'PySide2')
if __name__ == '__main__':
main()
Using the following command:
python convert_pyqt5_to_pyside2.py -i /path/of/PyQt5-folder -o fakeuic
Then you can use the loadUiType method from fakeuic:
from fakeuic import loadUiType
from PySide2 import QtCore, QtGui, QtWidgets
Ui_FirstWindow, QFirstWindow = loadUiType('first_window.ui')
Ui_SecondWindow, QSecondWindow = loadUiType('second_window.ui')
class First(QFirstWindow, Ui_FirstWindow):
def __init__(self):
super(First, self).__init__()
self.setupUi(self)
self.button.clicked.connect(self.show_second_window)
def show_second_window(self):
self.Second = Second()
self.Second.show()
class Second(QSecondWindow, Ui_SecondWindow):
def __init__(self):
super(Second, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
You can find the complete example here
PySide2 brought back loadUiType in May 2020. So if you upgrade, you can get a drop-in replacement. The only difference is the import:
from PySide2.QtUiTools import loadUiType
Syntax is the same (you will use loadUiType(<file>)[0] )
Follow these simple steps:
Assuming the ui file from qt designer is mycode.ui, convert this to the py file using the pyside2 ui converter by typing "pyside2-uic mycode.ui -o mycode.py" without the quotes. (Note use the pyside2 converter of pyside2-uic and not pyqt5 converter of pyuic5)
With mycode.py generated by pyside2 format, just replace all the headers for the PyQt5 code to "import sys" and "from mycode import *"
You are done...Hope this helps

Categories