I'm using PyQt5.
The goal is to display multiple icons/ Images in a QListWidget and have the data as text next to it.
The data is taken from a specific folder and the paths of each image get converted into icons.
Unfortunately it seems that I have to create an individual Item for each Icon using QtGui.QIcon and then assign the created QIcon to single variable that contains QtWidget.QListWidgetItem() method.
That ofc is quite inefficient. I want to dynamically include or delete parts of the database and have the list adjust accordingly.
If I try to write a for loop that iterates over i in icon_list and try to use the QtWidgets.QListWidgetItem() method on all of them, it returns an error:
TypeError: arguments did not match any overloaded call:
addItem(self, QListWidgetItem): argument 1 has unexpected type 'QIcon'
addItem(self, str): argument 1 has unexpected type 'QIcon'
Any suggestions on how to display a list of images + information more easily in PyQT5?
from PyQt5 import QtWidgets, QtGui
from PyQt5 import QtCore
from PyQt5.QtGui import QPixmap, QImage, QStandardItemModel, QStandardItem
import random
import sys
import os
class MainScreen(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setupUi(self)
## pictures
path = "/Users/lucasszikszai/Desktop/Coding/Galerie/Datenbank/Julio Rondo/"
self.name_list = os.listdir("/Users/lucasszikszai/Desktop/Coding/Galerie/Datenbank/Julio Rondo")
#self.picture_label.setPixmap(QPixmap(f"/{path}{self.name_list[1]}"))
self.full_paths = [path + i for i in self.name_list]
## convert pictures to icons
icon1 = QtGui.QIcon(path+self.name_list[1])
icon_list = [QtGui.QIcon(icon) for icon in self.full_paths]
# .addItems(list) takes a list of something and displays it
self.inventory.setIconSize(QtCore.QSize(250, 250))
self.inventory.addItems(self.name_list)
item = QtWidgets.QListWidgetItem(icon1, "Test")
#self.inventory.addItems(QtWidgets.QListWidgetItem(icon_list, "Test"))
self.inventory.addItem(item)
## buttons
self.hit_button.clicked.connect(self.generator)
def generator(self):
r_number = random.randint(1, 100)
self.number_display.setText(f"{str(r_number)}")
return r_number
if __name__ == "__main__":
app = QtWidgets.QApplication([])
widget = MainScreen()
widget.show()
app.exec()```
Related
I'm trying to build an app here. I used QT Designer to build the main window (Ui_MainWindow) with buttons. I import this to a new file where I can structure the code a bit better.
Anyhow, I keep getting the error "TypeError: startfile: filepath should be string, bytes or os.PathLike, not Ui_MainWindow" whenever I try to get the filename via QFileDialog. This filename is used in the GetData -method to produce a dataframe. I'm sure I'm doing something horribly wrong here in my code. I understood that you can call methods within other methods
So I will have 3 buttons:
Open folder (which gets the filename)
Update data (which is connected to UpdateData method. This method updates the data as I want)
Calculate (a method that calculates something based on the output from updateData -method.)
So I am trying to get an output from step 1 to use as input in step 2, to get an output which then would be used as input in step 3 and then - voilá.
What am I doing wrong?
from myQTDesignerGUIfile import Ui_MainWindow
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QLabel, QFileDialog, QMessageBox)
from PyQt5.QtCore import pyqtSlot, QFileInfo
class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
#Build instance of setpUI in Ui_MainWindow -class
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def GetFileName(self):
FileFilter = 'File (*.xlsx *.xlsm *.csv)'
FileName = QFileDialog.getOpenFileName(parent = self,
caption="Select File",
directory = 'Some Path',
filter = FileFilter)[0]
path = str(FileName)
if path:
print(path)
return path
def GetData(self):
path = self.GetFileName
return pd.read_csv(path)
def UpdateData(self):
## get data using the GetData -method
df = self.GetData()
## code to modify data is written here
return final_mod_data
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MyApp()
w.show()
app.exec()
Is there a way (or maybe a different widget i can use (i couldn't find any) so that i can make my combobox look something like the combobox in the picture ?
The picture shows what i want put with font. I would like the options to be my list instedt of the font.
I would like to see all the option (if there are to many to be able to scroll) and select one.
Here is my code so far:
from PyQt5 import QtCore, QtWidgets
import sys
from PyQt5 import QtGui, QtWidgets, QtPrintSupport
class Thired(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Thired, self).__init__(parent)
self.bb = QtWidgets.QComboBox(self)
self.bb.setGeometry(QtCore.QRect(212, 50, 400, 25))
self.bb.setEditable(True)
bpas = ['a','b','c']
self.bb.addItem("")
self.bb.setItemText(0, "")
for bpa in bpas:
self.bb.addItem(bpa)
self.bb.move(50, 200)
self.bb.activated[str].connect(self.style_choice)
def font_choice(self):
font, valid = QtWidgets.QFontDialog.getFont()
if valid:
self.styleChoice.setFont(font)
def style_choice(self, text):
self.styleChoice.setText(text)
QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create(text))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
gui = Thired()
gui.show()
app.exec_()
Edit:
I would like that when the whindow opens that all my option are always beeing shown. So that i do not have to press the dropdown arror. In different words: If the window is beeing opened there is a list of bpas, i want to be able to select from the list one of the bpa/option and send a singal that i choose this bpa.
To explain myself a little more (this is not been shown anywhere in the code): bpas = ['a','b','c'] are projects, and I want the user to seleced one of them and after selecting it the programm will load its conneced database. With dropdown it works, but i dont like the way dorpdown looks like with a lot of options :)
You can use a QListWidget with a QLineEdit:
from PyQt5 import QtCore, QtWidgets
import string
class Thired(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Thired, self).__init__(parent)
self.line_edit = QtWidgets.QLineEdit()
self.list_widget = QtWidgets.QListWidget()
options = list(string.ascii_letters)
self.list_widget.addItems(options)
self.list_widget.itemClicked.connect(self.on_itemClicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.line_edit)
lay.addWidget(self.list_widget)
self.resize(640, 480)
#QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
def on_itemClicked(self, item):
self.line_edit.setText(item.text())
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
gui = Thired()
gui.show()
sys.exit(app.exec_())
I need to generate a custom popup input window triggered by clicking a QPushButton in my app (via clicked). It needs to get several inputs from the user of different types and then return them to the calling function inside the main window app. I have found built in functions such as QInputDialog that can do this for single specific inputs, but I can't figure out how to do this in the case of a popup that asks for several inputs of different types at once (preferably in a window designed in Qt Designer). Does anyone know how to do this?
import sys
import os
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import uic
path = os.path.dirname(__file__) #uic paths from itself, not the active dir, so path needed
qtCreatorFile = "NAME.ui" #Ui file name, from QtDesigner
Ui_MainWindow, QtBaseClass = uic.loadUiType(path + qtCreatorFile) #process through pyuic
class MyApp(QMainWindow, Ui_MainWindow): #gui class
def __init__(self):
#Set up the gui via Qt
super(MyApp, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.add_button.clicked.connect(self.add_row) #add_button is QPushButton
def add_row(self):
data1, data2, data3 = #popup form to get data (types are not the same)
#do stuff with data
pass
#start app
if __name__ == "__main__":
app = QApplication(sys.argv) #instantiate a QtGui (holder for the app)
window = MyApp()
window.show()
sys.exit(app.exec_())
There is no single solution but I will give you a guide to do what you want.
If you want to get a widget with the behavior of QInputDialog you must first choose the right template, in this case a good option is Dialog with Buttons Bottom or Dialog with Buttons Right, add the components you want, position it, etc.
Then as you show your code you create a class that inherits from QDialog and then create a method where you get the results but to do so do not use show() but exec_()
path = os.path.dirname(__file__)
qtCreatorFile = "some_dialog.ui"
Ui_Dialog, _ = uic.loadUiType(os.path.join(path,qtCreatorFile))
class CustomDialog(QDialog, Ui_Dialog):
def __init__(self):
super(CustomDialog, self).__init__()
self.setupUi(self)
# set initials values to widgets
def getResults(self):
if self.exec_() == QDialog.Accepted:
# get all values
val = self.some_widget.some_function()
val2 = self.some_widget2.some_another_function()
return val1, val2, ...
else:
return None
And then use it in your function:
class MyApp(QMainWindow, Ui_MainWindow): #gui class
def __init__(self):
#Set up the gui via Qt
super(MyApp, self).__init__()
self.setupUi(self)
self.add_button.clicked.connect(self.add_row) #add_button is QPushButton
def add_row(self):
w = CustomDialog()
values = w.getResults()
if values:
data1, data2, data3 = values
I'm still quite a newbie with Python and PyQt5, so I have a really basic question. My idea is to build application to download a URL. Here is a picture of my design:
When I right click on the URL from any website, copy it, and go to my application and press on icon on toolbar named (Add URL), the URL should be pasted immediately inside the QLineEdit.
Here is my code:
from PyQt5.QtWidgets import*
from PyQt5.QtCore import*
from PyQt5.QtGui import*
from PyQt5.uic import loadUiType
from PyQt5.QtWidgets import QApplication ,QMainWindow,QAction
from os import path
import sys
FORM_CLASS,_= loadUiType(path.join(path.dirname(__file__),"main.ui"))
class MainApp(QMainWindow , FORM_CLASS):
def __init__(self, parent=None):
super(MainApp, self).__init__(parent)
QMainWindow.__init__(self)
self.setupUi(self)
self.idm_UI()
self.idm_Buttons()
def idm_UI(self):
self.setWindowTitle("Download URL")
self.setFixedSize(631,400)
self.setWindowIcon(QIcon("download.jpg"))
# To Create the Icone
exitAct = QAction(QIcon('exit.png'),'Exit',self)
exitAct.triggered.connect(self.idm_exit)
pasteAction = QAction(QIcon("paste.png"), "Add URL", self)
pasteAction.triggered.connect(self.idm_add)
self.toolbar = self.addToolBar('Toolbar')
self.toolbar.addAction(exitAct)
self.toolbar.addAction(pasteAction)
def idm_exit(self):
self.close()
def idm_add(self): # What is the right method that I can use to paste the URL inside lineEdit_4?
pass
The name of define method of function is
def def idm_add(self):
So, what function or method do I need to use to paste the URL inside the LineEditor box?
What you are to paste the text that is stored in the clipboard, for this you must use QClipboard.
def idm_add(self):
clipboard = QApplication.clipboard()
self.lineEdit_4.setText(clipboard.text())
I have data coming from two sources , one from XML file save paths , second one from QFileSystemModel which I want to work if the user couldn't see the path then in QLineEdit the user should be able to browse path !! the first letter obviously "/" or single letter for windows .
just for the example I have simple replaced the XMLData from file to defaultList of paths.
The below code works for a while but I get segmentation fault.
from PyQt4.Qt import Qt, QObject,QLineEdit
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
from PyQt4 import QtGui, QtCore
import sys
class DirLineEdit(QLineEdit, QtCore.QObject):
"""docstring for DirLineEdit"""
def __init__(self):
super(DirLineEdit, self).__init__()
self.defaultList = ['~/Development/python/searchMethod', '~/Development/Nuke_python',
'~/Development/python/openexr', '~/Development/python/cpp2python',
'~/Development/python/using_argparse', '~Development/python/listFilter']
self.textChanged.connect(self.switchCompleter)
self._pathsList()
def focusInEvent(self, event):
QtGui.QLineEdit.focusInEvent(self, event)
self.completer().complete()
def switchCompleter(self):
if len(self.text()) >= 1:
self.__dirCompleter()
if len(self.text()) == 0:
self.__pathsList()
def __dirCompleter(self):
dirModel = QtGui.QFileSystemModel()
dirModel.setRootPath(QtCore.QDir.currentPath())
dirModel.setFilter(QtCore.QDir.AllDirs | QtCore.QDir.NoDotAndDotDot | QtCore.QDir.Files)
dirModel.setNameFilterDisables(0)
completer = QtGui.QCompleter(dirModel, self)
completer.setModel(dirModel)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.setCompleter(completer)
def _pathsList(self):
completerList = QtCore.QStringList()
for i in self.defaultList:
completerList.append(QtCore.QString(i))
lineEditCompleter = QtGui.QCompleter(completerList)
lineEditCompleter.setCompletionMode(QtGui.QCompleter.UnfilteredPopupCompletion)
self.setCompleter(lineEditCompleter)
app = QtGui.QApplication(sys.argv)
smObj = DirLineEdit()
smObj.show()
app.exec_()
the above code gives Segmentation fault: 11
Is there a better way I can use both completer with one ?