I'm looking for a way to get the value or text of all the user inputs/lineedits of the app
I'm creating an app that creates multiple folders at once. There are multiple user inputs to write in the name of the folders, that I create by calling the same function multiple times. Using this "self.le2.text()" only gets the value of the first user input created.
Here's my code so far. Essentially I want the "create folders" button to create all the folders from all the user inputs created by the "new_folder" function. Right now its only getting the value of the first one created.
import sys
import os
from PySide6 import QtWidgets, QtCore, QtGui
from PySide6.QtWidgets import QApplication
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
#set central widget and layout
self.setWindowTitle("Amazing Folder Generator")
self.generalLayout = QtWidgets.QVBoxLayout()
self.centralWidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralWidget)
self.centralWidget.setLayout(self.generalLayout)
self.le1 = QtWidgets.QLineEdit()
self.file_path()
self.button1 = QtWidgets.QPushButton("New Folder")
self.generalLayout.addWidget(self.button1)
self.button1.pressed.connect(self.new_folder)
self.button2 = QtWidgets.QPushButton("Create Folders")
self.generalLayout.addWidget(self.button2)
self.button2.pressed.connect(self.create_files)
self.new_folder()
self.new_folder()
self.new_folder()
def file_path(self):
self.le1 = QtWidgets.QLineEdit()
self.le1.setFixedHeight(20)
self.le1.setAlignment(QtCore.Qt.AlignRight)
self.path_layout = QtWidgets.QFormLayout()
self.path_layout.addRow("Folder Path: ", self.le1)
self.generalLayout.addLayout(self.path_layout)
def new_folder(self):
self.le2 = QtWidgets.QLineEdit()
self.le2.setFixedHeight(20)
self.le2.setAlignment(QtCore.Qt.AlignRight)
self.path_layout = QtWidgets.QFormLayout()
filename = "File: "
self.path_layout.addRow(filename, self.le2)
self.generalLayout.addLayout(self.path_layout)
def create_files(self):
path = self.le1.text() + "\\"
filename = self.le2.text()
newpath = path + filename
if not os.path.exists(newpath):
os.makedirs(newpath)
else:
print("folder already exists")
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The simple solution is to store the QLineEdits in a list and then iterate to get the text. In this case I have rewritten your code to make it more readable.
import sys
import os
import os.path
from PySide6 import QtWidgets, QtCore, QtGui
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("Amazing Folder Generator")
self.folder_le = QtWidgets.QLineEdit(alignment=QtCore.Qt.AlignRight)
self.folder_le.setFixedHeight(20)
self.add_row_button = QtWidgets.QPushButton("New Folder")
self.create_button = QtWidgets.QPushButton("Create Folders")
self.files_layout = QtWidgets.QFormLayout()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.form_layout = QtWidgets.QFormLayout(central_widget)
self.form_layout.addRow("Folder Path:", self.folder_le)
self.form_layout.addRow(self.add_row_button)
self.form_layout.addRow(self.create_button)
self.form_layout.addRow(self.files_layout)
self._files_le = []
self.add_row_button.clicked.connect(self.add_row)
self.create_button.clicked.connect(self.create_files)
for _ in range(3):
self.add_row()
#property
def folder(self):
return self.folder_le.text()
#property
def filenames(self):
return [le.text() for le in self._files_le]
def add_row(self):
le = QtWidgets.QLineEdit(alignment=QtCore.Qt.AlignRight)
le.setFixedHeight(20)
self.files_layout.addRow("File:", le)
self._files_le.append(le)
def create_files(self):
for filename in self.filenames:
newpath = os.path.join(self.folder, filename)
if not os.path.exists(newpath):
os.makedirs(newpath)
else:
print("folder already exists")
def main():
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Related
I have QfileSysteModel and QSortFilterProxyModel. When I try to call QfileSysteModel.filePath to get the current index of the file Error occurs as core Dump. Here is a piece of code
le = QLineEdit()
lv = QListView()
file_model = QFileSystemModel()
file_model.setRootPath(QtCore.QDir.rootPath())
proxy_model = QSortFilterProxyModel(
recursiveFilteringEnabled=True,
filterRole=QtWidgets.QFileSystemModel.FileNameRole)
proxy_model.setSourceModel(file_model)
lv.setModel(self.proxy_model)
It works well, but when I try to call any methods of the QFileSystemModel Core Dumps. for example
filepath = file_model.filePath(lv.currentIndex())
How can I use any method of the QfileSystemModel
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
le = QtWidgets.QLineEdit()
self.lv = QtWidgets.QListView()
self.file_model = QtWidgets.QFileSystemModel()
self.file_model.setRootPath(QtCore.QDir.rootPath())
self.proxy_model = QtCore.QSortFilterProxyModel(
recursiveFilteringEnabled=True,
filterRole=QtWidgets.QFileSystemModel.FileNameRole)
self.proxy_model.setSourceModel(self.file_model)
self.lv.setModel(self.proxy_model)
root_index = self.file_model.index(QtCore.QDir.rootPath())
proxy_index = self.proxy_model.mapFromSource(root_index)
self.lv.setRootIndex(proxy_index)
self.lv.doubleClicked.connect(self.navigate)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(le)
lay.addWidget(self.lv)
def navigate(self):
# Get the path of file or folder
filepath = self.file_model.filePath(self.lv.currentIndex())
print(filepath)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
When working with a proxy model, the ModelIndex of the proxy differs from the index in the source model. Use mapToSource() to convert from proxy model to source model.
In your case, it would probably look like this:
# alternative one: do not reference proxy_model directly
filepath = file_model.filePath(lv.model().mapToSource(lv.currentIndex()))
# alternative two:
filepath = file_model.filePath(self.proxy_model.mapToSource(lv.currentIndex()))
I want to make a help file using QtHelp and QHelpEngine. I currently have some code but I am not sure about my errors and the documentation is a little vague in my opinion. Nonetheless the current issue I am facing is one of connecting signal and slots. The error I currently get is AttributeError: 'builtin_function_or_method' object has no attribute 'linkActivated' Not sure the reason for this as the documentation states that contentWidget does have a signal called linkActivated. And an error occurs here textViewer = QtWidgets.QTextBrowser(helpEngine)
Reference
from PyQt5 import QtCore, QtGui, QtWidgets, QtHelp
import os
class Ui_HelpSetupClass(QtWidgets.QDockWidget):
def __init__(self):
super().__init__()
self.setupUi(self)
def setupUi(self, HelpSetupClass):
qUrl = "qthelp://ut.tool.help/tool/index.html"
HELP_DIR = os.getcwd()
HELP_PATH = HELP_DIR + "\\" + "Help" + "\\" + "help_file.qhc"
helpEngine = QtHelp.QHelpEngine(HELP_PATH)
helpEngine.setupData()
tableWidget = QtWidgets.QTabWidget()
tableWidget.setMaximumWidth(200)
tableWidget.addTab(helpEngine.contentWidget(), "Contents")
tableWidget.addTab(helpEngine.indexWidget(), "Index")
textViewer = QtWidgets.QTextBrowser(helpEngine)
textViewer.setSource(qUrl)
helpEngine.contentWidget.linkActivated(qUrl ).connect(textViewer.setSource(qUrl))
helpEngine.indexWidget.documentActivated(qUrl ).connect(textViewer.setSource(qUrl))
horizSplitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
horizSplitter.insertWidget(0, tableWidget)
horizSplitter.insertWidget(1, textViewer)
horizSplitter.hide()
helpWindow = QtWidgets.QDockWidget("Help", self)
helpWindow.setWidget(horizSplitter)
helpWindow.hide()
QtWidgets.QMainWindow.addDockWidget(QtCore.Qt.BottomDockWidgetArea, helpWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ui = Ui_HelpSetupClass()
ui.show()
sys.exit(app.exec_())
In your translation of the C++ code to Python it shows many errors so I will avoid pointing it out and I will only show the correct translation:
import os
from PyQt5 import QtCore, QtGui, QtWidgets, QtHelp
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
class HelpBrowser(QtWidgets.QTextBrowser):
def __init__(self, helpEngine, parent=None):
super().__init__(parent)
self.helpEngine = helpEngine
def loadResource(self, _type, name):
if name.scheme() == "qthelp":
return self.helpEngine.fileData(name)
else:
return super().loadResource(_type, name)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.scene = QtWidgets.QGraphicsScene()
self.scene.setSceneRect(0, 0, 400, 200)
self.view = QtWidgets.QGraphicsView(self.scene)
self.view.setDragMode(QtWidgets.QGraphicsView.RubberBandDrag)
self.view.setRenderHints(QtGui.QPainter.Antialiasing)
self.setCentralWidget(self.view)
self.createHelpWindow()
self.createActions()
self.createMenus()
self.createConnections()
self.setWindowTitle(self.tr("QGraphicsScene Help Example"))
self.resize(640, 480)
def createHelpWindow(self):
self.helpEngine = QtHelp.QHelpEngine(
os.path.join(CURRENT_DIR, "documentation", "qgraphicshelpexample.qhc")
)
self.helpEngine.setupData()
tWidget = QtWidgets.QTabWidget()
tWidget.setMaximumWidth(200)
tWidget.addTab(self.helpEngine.contentWidget(), "Contents")
tWidget.addTab(self.helpEngine.indexWidget(), "Index")
textViewer = HelpBrowser(self.helpEngine)
textViewer.setSource(
QtCore.QUrl("qthelp://walletfox.qt.helpexample/doc/index.html")
)
self.helpEngine.setUsesFilterEngine(True)
self.helpEngine.contentWidget().linkActivated.connect(textViewer.setSource)
self.helpEngine.indexWidget().linkActivated.connect(textViewer.setSource)
horizSplitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
horizSplitter.insertWidget(0, tWidget)
horizSplitter.insertWidget(1, textViewer)
horizSplitter.hide()
self.helpWindow = QtWidgets.QDockWidget(self.tr("Help"), self)
self.helpWindow.setWidget(horizSplitter)
self.helpWindow.hide()
self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.helpWindow)
def createActions(self):
self.insertEllipseAction = QtWidgets.QAction(self.tr("Insert &Ellipse"), self)
self.insertEllipseAction.setIcon(QtGui.QIcon(":/icons/ellipse.png"))
self.insertRectangleAction = QtWidgets.QAction(
self.tr("Insert &Rectangle"), self
)
self.insertRectangleAction.setIcon(QtGui.QIcon(":/icons/rectangle.png"))
self.helpAction = QtWidgets.QAction(self.tr("Help Contents..."), self)
self.helpAction.setShortcut(QtGui.QKeySequence.HelpContents)
self.aboutAction = QtWidgets.QAction(self.tr("&About"), self)
def createMenus(self):
self.itemMenu = QtWidgets.QMenu(self.tr("&Item"), self)
self.itemMenu.addAction(self.insertEllipseAction)
self.itemMenu.addAction(self.insertRectangleAction)
self.helpMenu = QtWidgets.QMenu(self.tr("&Help"), self)
self.helpMenu.addAction(self.helpAction)
self.helpMenu.addAction(self.aboutAction)
self.menuBar().addMenu(self.itemMenu)
self.menuBar().addMenu(self.helpMenu)
def insertItem(self):
action = self.sender()
if isinstance(action, QtWidgets.QAction):
itemToAdd = None
mPen = QtGui.QPen(QtCore.Qt.black, 3, QtCore.Qt.SolidLine)
eBrush = QtGui.QBrush(QtGui.QColor("#FF7F50"))
rBrush = QtGui.QBrush(QtGui.QColor("#CC0000"))
if action.iconText() == "Insert Ellipse":
itemToAdd = self.scene.addEllipse(0, 0, 150, 75, mPen, eBrush)
elif action.iconText() == "Insert Rectangle":
itemToAdd = self.scene.addRect(0, 0, 100, 100, mPen, rBrush)
if itemToAdd is not None:
itemToAdd.setFlags(
QtWidgets.QGraphicsItem.ItemIsSelectable
| QtWidgets.QGraphicsItem.ItemIsMovable
)
def about(self):
QtWidgets.QMessageBox.about(
self,
self.tr("About QGraphicsScene Help Example"),
self.tr(
"This example demonstrates how to implement\n"
"help for a Qt application."
),
)
def createConnections(self):
self.insertEllipseAction.triggered.connect(self.insertItem)
self.insertRectangleAction.triggered.connect(self.insertItem)
self.helpAction.triggered.connect(self.helpWindow.show)
self.aboutAction.triggered.connect(self.about)
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_A:
for item in self.scene.selectedItems():
self.scene.removeItem(item)
else:
super().keyPressEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Note: Using the original file "qgraphicshelpexample.qhp" causes me errors since the "./foo" paths like "./insertobject.html" are not resolved correctly so I change them to "foo".
The complete example can be found here.
I read this: How to resize QInputDialog, PyQt but it didnt work for me, as it seems to be about PyQt4
This is my code snipplet:
def ImportURL(self): #URL dialog aufrufen
InputDialog = QtWidgets.QInputDialog(self)
i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")
if okPressed:
self.getWebsite(i)
And i tried adding .setFixedSize in the 2nd line. I tried adding InputDialog.setFixedSite(self) between line 2 and 3. Nothing worked, it either crashes or it creates a second, empty window. Am i overlooking something here?
In the answers to the other question do not explain the cause of the problem so in my answer will try to cover as much as possible
Explanation:
The getText() method is a static method, which means that an object is not used, in the method internally if it is used but it is not accessible. So the InputDialog that you create is not the one you show and this you can check using the following code since you will see 2 windows:
def ImportURL(self):
InputDialog = QtWidgets.QInputDialog(self)
InputDialog.show()
i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")
if okPressed:
self.getWebsite(i)
Solutions:
So there are the following solutions:
Taking advantage of what you have passed as a parent to self, you can obtain the object using findChildren:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
button = QtWidgets.QPushButton(
"Open QInputDialog", clicked=self.ImportURL
)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(button)
#QtCore.pyqtSlot()
def ImportURL(self):
QtCore.QTimer.singleShot(0, self.after_show)
i, okPressed = QtWidgets.QInputDialog.getText(
self,
"Import website",
"Site to import:",
QtWidgets.QLineEdit.Normal,
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite",
)
if okPressed:
# self.getWebsite(i)
print(i)
#QtCore.pyqtSlot()
def after_show(self):
size = QtCore.QSize(500, 100)
for d in self.findChildren(QtWidgets.QInputDialog):
if d.isVisible():
d.resize(size)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Do not use the getText() method but create an object that implements the same logic:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
button = QtWidgets.QPushButton(
"Open QInputDialog", clicked=self.ImportURL
)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(button)
#QtCore.pyqtSlot()
def ImportURL(self):
dialog = QtWidgets.QInputDialog(self)
dialog.resize(QtCore.QSize(500, 100))
dialog.setWindowTitle("Import website")
dialog.setLabelText("Site to Import")
dialog.setTextValue(
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
)
dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
i = dialog.textValue()
print(i)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Update:
The layout of the QInputDialog has QLayout::SetMinAndMaxSize set as sizeConstraint, so the fixed size will not work, the trick is to change it to QLayout::SetDefaultConstraint:
from functools import partial
# ...
#QtCore.pyqtSlot()
def ImportURL(self):
dialog = QtWidgets.QInputDialog(self)
dialog.setWindowTitle("Import website")
dialog.setLabelText("Site to Import")
dialog.setTextValue(
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
)
dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
wrapper = partial(self.on_timeout, dialog)
QtCore.QTimer.singleShot(0, wrapper)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
i = dialog.textValue()
print(i)
def on_timeout(self, dialog):
lay = dialog.layout()
lay.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
dialog.setFixedSize(QtCore.QSize(500, 100))
I am populating a QlistWidget with icons and I notice there is a lag when the window is loading. I wondered if there is a way to generate half resolution icons, or some other way to speed up the window generation time?
texture_item = QtWidgets.QListWidgetItem(texture)
texture_pixmap = QtGui.QPixmap(image_path)
texture_icon = QtGui.QIcon()
self.list_widget_left.setIconSize(QtCore.QSize(105,105))
texture_item.setFont(QtGui.QFont('SansSerif', 10))
texture_icon.addPixmap(texture_pixmap)
texture_item.setIcon(texture_icon)
self.list_widget_left.addItem(texture_item)
texture_item.setTextAlignment(Qt.AlignBottom)
There are several aspects that can generate the delay:
The images weigh a lot then the solution is to use less heavy icons
You have many images that iterate in the same loop, then a possible solution is to give a small delay so that the image is loaded little by little avoiding the visual delay that you indicate.
import os
from PySide2 import QtCore, QtGui, QtWidgets
import shiboken2
def for_loop_files(path, interval=100, extensions=(), parent=None, objectName=""):
timer = QtCore.QTimer(parent=parent, singleShot=True, interval=interval)
if objectName:
timer.setObjectName(objectName)
loop = QtCore.QEventLoop(timer)
timer.timeout.connect(loop.quit)
timer.destroyed.connect(loop.quit)
for root, dirs, files in os.walk(path):
for name in files:
base, ext = os.path.splitext(name)
if extensions:
if ext in extensions:
if shiboken2.isValid(timer):
timer.start()
loop.exec_()
yield os.path.join(root, name)
else:
yield os.path.join(root, name)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.list_widget = QtWidgets.QListWidget()
self.list_widget.setViewMode(QtWidgets.QListView.IconMode)
self.list_widget.setIconSize(QtCore.QSize(128, 128))
self.list_widget.setResizeMode(QtWidgets.QListView.Adjust)
self.list_widget.setFlow(QtWidgets.QListView.TopToBottom)
self.setCentralWidget(self.list_widget)
self.resize(640, 480)
QtCore.QTimer.singleShot(0, self.load_icons)
#QtCore.Slot()
def load_icons(self):
for path in for_loop_files(".", extensions=(".png", "jpg"), parent=self, objectName="icon_timer", interval=30):
it = QtWidgets.QListWidgetItem()
it.setIcon(QtGui.QIcon(path))
self.list_widget.addItem(it)
def closeEvent(self, event):
timer = self.findChild(QtCore.QTimer, "icon_timer")
if timer is not None:
timer.deleteLater()
super(MainWindow, self).closeEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
from PySide2 import QtCore, QtGui, QtWidgets
import shiboken2
def for_loop_files(paths, interval=100, parent=None, objectName=""):
timer = QtCore.QTimer(parent=parent, singleShot=True, interval=interval)
if objectName:
timer.setObjectName(objectName)
loop = QtCore.QEventLoop(timer)
timer.timeout.connect(loop.quit)
timer.destroyed.connect(loop.quit)
for path in paths:
if shiboken2.isValid(timer):
timer.start()
loop.exec_()
yield path
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.list_widget = QtWidgets.QListWidget()
self.list_widget.setViewMode(QtWidgets.QListView.IconMode)
self.list_widget.setIconSize(QtCore.QSize(128, 128))
self.list_widget.setResizeMode(QtWidgets.QListView.Adjust)
self.list_widget.setFlow(QtWidgets.QListView.TopToBottom)
self.setCentralWidget(self.list_widget)
self.resize(640, 480)
QtCore.QTimer.singleShot(0, self.load_icons)
#QtCore.Slot()
def load_icons(self):
paths = ["icon1.png", "icon2.png", "icon3.png", "icon4.png"]
for path in for_loop_files(paths, parent=self, objectName="icon_timer", interval=30):
it = QtWidgets.QListWidgetItem()
it.setIcon(QtGui.QIcon(path))
self.list_widget.addItem(it)
def closeEvent(self, event):
timer = self.findChild(QtCore.QTimer, "icon_timer")
timer.deleteLater()
super(MainWindow, self).closeEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I'm using Python 2.7 and Qt designer and I'm new to MVC:
I have a View completed within Qt to give me a directory tree list, and the controller in place to run things. My question is:
Given a Qtree view, how may I obtain a directory once a dir is selected?
Code snap shot is below, I suspect it's SIGNAL(..) though I'm unsure:
class Main(QtGui.QMainWindow):
plot = pyqtSignal()
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# create model
model = QtGui.QFileSystemModel()
model.setRootPath( QtCore.QDir.currentPath() )
# set the model
self.ui.treeView.setModel(model)
**QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL('clicked()'), self.test)**
def test(self):
print "hello!"
The signal you're looking for is selectionChanged emmited by the selectionModel owned by your tree. This signal is emmited with the selected item as first argument and the deselected as second, both are instances of QItemSelection.
So you might want to change the line:
QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL('clicked()'), self.test)
to
QtCore.QObject.connect(self.ui.treeView.selectionModel(), QtCore.SIGNAL('selectionChanged()'), self.test)
Also I recommend you to use the new style for signals and slots. Redefine your test function as:
#QtCore.pyqtSlot("QItemSelection, QItemSelection")
def test(self, selected, deselected):
print("hello!")
print(selected)
print(deselected)
Here you have a working example:
from PyQt4 import QtGui
from PyQt4 import QtCore
class Main(QtGui.QTreeView):
def __init__(self):
QtGui.QTreeView.__init__(self)
model = QtGui.QFileSystemModel()
model.setRootPath( QtCore.QDir.currentPath() )
self.setModel(model)
QtCore.QObject.connect(self.selectionModel(), QtCore.SIGNAL('selectionChanged(QItemSelection, QItemSelection)'), self.test)
#QtCore.pyqtSlot("QItemSelection, QItemSelection")
def test(self, selected, deselected):
print("hello!")
print(selected)
print(deselected)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
PyQt5
In PyQt5 is a little bit different (thanks to Carel and saldenisov for comments and aswer.)
... connect moved from being an object method to a method acting upon the attribute when PyQt went from 4 to 5
So instead the known:
QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL('clicked()'), self.test)
now you write:
class Main(QTreeView):
def __init__(self):
# ...
self.setModel(model)
self.doubleClicked.connect(self.test) # Note that the the signal is now a attribute of the widget.
Here is a the example (by saldenisov) using PyQt5.
from PyQt5.QtWidgets import QTreeView,QFileSystemModel,QApplication
class Main(QTreeView):
def __init__(self):
QTreeView.__init__(self)
model = QFileSystemModel()
model.setRootPath('C:\\')
self.setModel(model)
self.doubleClicked.connect(self.test)
def test(self, signal):
file_path=self.model().filePath(signal)
print(file_path)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
In PyQt5 it can be done in this way:
from PyQt5.QtWidgets import QTreeView,QFileSystemModel,QApplication
class Main(QTreeView):
def __init__(self):
QTreeView.__init__(self)
model = QFileSystemModel()
model.setRootPath('C:\\')
self.setModel(model)
self.doubleClicked.connect(self.test)
def test(self, signal):
file_path=self.model().filePath(signal)
print(file_path)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
If I understand the question correctly you would like the directory or file name selected.
This is what I do:
from PyQt4 import QtGui
from PyQt4 import QtCore
# ---------------------------------------------------------------------
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(600,400)
self.setWindowTitle("Treeview Example")
self.treeview = QtGui.QTreeView(self)
self.treeview.model = QtGui.QFileSystemModel()
self.treeview.model.setRootPath( QtCore.QDir.currentPath() )
self.treeview.setModel(self.treeview.model)
self.treeview.setColumnWidth(0, 200)
self.setCentralWidget(self.treeview)
self.treeview.clicked.connect(self.on_treeview_clicked)
# ---------------------------------------------------------------------
#QtCore.pyqtSlot(QtCore.QModelIndex)
def on_treeview_clicked(self, index):
indexItem = self.treeview.model.index(index.row(), 0, index.parent())
# path or filename selected
fileName = self.treeview.model.fileName(indexItem)
# full path/filename selected
filePath = self.treeview.model.filePath(indexItem)
print(fileName)
print(filePath)
# ---------------------------------------------------------------------
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I tried this alternative to get the file name...
Instead of:
indexItem = self.treeview.model.index(index.row(), 0, index.parent())
# path or filename selected
fileName = self.treeview.model.fileName(indexItem)
I tried:
# path or filename selected
fileName = index.internalPointer().fileName
Which also seems to work...