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 ?
Related
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()```
I want to design my QWizardPages in Qt Designer and I want to load them into my Python program with PySide2. Previously I have been using PyQt5 without any problems but making the switch to PySide2 seems harder then expected.
The problem I am facing is that when I am adding a QWizardPage to my QWizard , the page is indeed added to the Wizard, but also an other (empty) page is added. I'm not able to find what I'm doing wrong so I was wondering if someone can have a look.
I have tried to add the pages with both the functions addPage() and setPage(), but they give the same results. What I also noticed is that when I explicitely set the Title of the page with setTitle(), the empty (unwanted) page gets this title, but not the page I designed in Qt Designer.
import os
import sys
from PySide2.QtWidgets import QWizard, QWizardPage, QApplication
from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
from enum import Enum
class MyWizard(QWizard):
def __init__(self):
super().__init__()
self.setPage(PageNumbers.page_one.value, PageOne(self))
class PageOne(QWizardPage):
def __init__(self, parent):
super().__init__(parent)
ui_file = os.path.join(__file__, '..', 'pageOne.ui')
file = QFile(ui_file)
file.open(QFile.ReadOnly)
loader = QUiLoader()
loader.load(file, parent)
file.close()
self.setTitle("This is another test Title")
class PageNumbers(Enum):
page_one = 1
if __name__ == '__main__':
app = QApplication(sys.argv)
wizard = MyWizard()
wizard.show()
app.exec_()
What I would expect is to have just one QWizardPage showing up with directly the Finish button. Instead I get two QWizardPages as shown in this image:
Can someone tell me what's going on?
(I get the expected result using PyQt5 with the following code: https://pastebin.com/6W2sx9M1)
The developers of PyQt implement functions to be able to create classes based on the .ui that is not implemented in Qt by default (Qt/C++ uses the MOC to do this work), but in the case of PySide2-Qt for python it does not implement it, only has the QUiLoader class that allows to create a widget based on the .ui unlike PyQt that allows filling a class.
In conclusion there is no equivalent in PySide2 of the loadUi function so you can not implement the same logic. PySide2 is not PyQt5, there are own equivalences since they use the same base but they have implementations, limitations and advantages.
Going to the practical problem, considering that the .ui is next to the .py the solution is the following:
import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
from enum import Enum
class PageNumbers(Enum):
page_one = 0
class MyWizard(QtWidgets.QWizard):
def __init__(self):
super().__init__()
ui_file = os.path.join(os.path.dirname(os.path.abspath(__file__)) ,'PageOne.ui')
page_one = create_widget(ui_file, self)
self.setPage(PageNumbers.page_one.value, page_one)
def create_widget(filename, parent=None):
file = QtCore.QFile(filename)
if not file.open(QtCore.QFile.ReadOnly):
return
loader = QtUiTools.QUiLoader()
widget = loader.load(file, parent)
return widget
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
wizard = MyWizard()
wizard.show()
sys.exit(app.exec_())
I'm still new with python and Qt designer. I would like to develop an application where user need to press the 'pushbutton' in order to view the image(from local directory path) on GUI mainwindow.This will keep repeating until complete number of cycle.
Did tried using QLabel and QGraphiscView widget but doesn't work.(probably due to lack of knowledge). Could anyone help me to solve it?
Below is the code:
#!/usr/bin/env python
from __future__ import division
import sys
from PyQt4 import QtCore, QtGui, uic
gui_file = 'image.ui'
Ui_MainWindow, QtBaseClass = uic.loadUiType(gui_file)
class showImage(QtGui.QMainWindow,Ui_MainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.get_image_button.clicked.connect(self.getImage)
def getImage(self):
image_path='c:/Users/mohd_faizal4/Desktop/Python/Image/image1.jpg' #path to image file
self.label_image.QPixmap(image_path)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myWindow = showImage()
myWindow.show()
sys.exit()
app.exec_()
Really appreciate!
The slot detectClipboardUrl of QClipboard::dataChanged() was called twice sometimes when I copy url in Google Chrome's address bar in this code, tested with PyQt5.7,Python3.5 on Win7 32bit, also on Linux Mint 18,
while I need the slot to be called only once , is this a bug ? any solutions ?
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QTableView):
def __init__(self, parent=None):
super().__init__(parent)
self.clipboard = QApplication.clipboard()
self.clipboard.dataChanged.connect(self.detectClipboardUrl)
#pyqtSlot()
def detectClipboardUrl(self):
print(self.clipboard.text())
if __name__ == "__main__":
app = QApplication(sys.argv)
ui = MainWindow()
ui.show()
sys.exit(app.exec_())
If the changes are duplicates, you can do something like:
class MainWindow(QTableView):
def __init__(self, parent=None):
self.clipboard = QApplication.clipboard()
self._cb_last = hash(self.clipboard.text())
self.clipboard.dataChanged.connect(self.detectClipboardUrl)
#pyqtSlot()
def detectClipboardUrl(self):
text = self.clipboard.text()
cb_current = hash(text)
if cb_current != self._cb_last:
print('clipboard text changed:', text)
self._cb_last = cb_current
The reason for using hash is simply to avoid keeping very large strings in memory.
Alternatively, if the two signals arrive very close together, you could use a QTimer to block any changes that occur within a few milliseconds of the first one.
UPDATE:
As I suspected, the problem is caused by a bug in Chromium: see Issue 173691.
I am trying to connect a push button signal to a callable I created, but for some reason this error keeps on popping up. I've checked to make sure QtCore is imported ... what else am I missing?
Sample code:
from PyQt4 import QtCore
from PyQt4 import QtGui
import sys
class guiFindFiles(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
#Create window
self.setFixedSize(400,180)
self.setWindowTitle("Choose the files to use")
#Create all layouts to be used by window
self.windowLayout = QtGui.QVBoxLayout()
self.fileLayout1 = QtGui.QHBoxLayout()
self.fileLayout2 = QtGui.QHBoxLayout()
self.fileLayout3 = QtGui.QHBoxLayout()
#Create the prompt for user to load in the q script to use
self.qFileTF = QtGui.QLineEdit("Choose the q script file to use")
self.qFileButton = QtGui.QPushButton("Open")
self.qFileButton.setFixedSize(100,27)
self.fileLayout1.addWidget(self.qFileTF)
self.fileLayout1.addWidget(self.qFileButton)
#Connect all the signals and slots
self.connect(self.qFileButton, SIGNAL("pressed()"), self.loadFile)
def loadFile():
fileName = []
selFile = QtGui.QFileDailog.getOpenFileName(self)
print selFile
SIGNAL is inside QtCore, so the line should be:
self.connect(self.qFileButton, QtCore.SIGNAL("pressed()"), self.loadFile)
but you really should use the new style connections:
self.qFileButton.pressed.connect(self.loadFile)
And, unless you meant to differentiate a click from press/release couple, you'd better use clicked signal:
self.qFileButton.clicked.connect(self.loadFile)
SIGNAL is defined inside QtCore, so you must use it within QtCore namespace if you've imported QtCore as a whole. So use:
QtCore.SIGNAL(...)
instead of:
SIGNAL(...)
Or you can import SIGNAL from QtCore explicitly:
from PyQt4.QtCore import SIGNAL