I'am a beginner with PyQt. All is in the title :I don't understand how can I get the path (and the name) from the selected file?
I wish later update a QListView with this path.
Here my script :
# -*- coding: utf-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
class MyWidget(QWidget):
# SIGNAUX
tree_model_indexSig = pyqtSignal(QModelIndex)
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
# connect signaux to slots
self.tree_model_indexSig.connect(self.indexSlot)
self.model = QFileSystemModel()
self.model.setRootPath(QDir.rootPath())
''' GUI '''
# instantiation du treeview et du listview
self.treeView = QTreeView(self)
self.treeView.setGeometry(QRect(10, 20, 601, 231))
self.treeView.setObjectName("treeView")
''' END GUI '''
self.treeView.setModel(self.model)
self.treeView.setRootIndex(self.model.index(QDir.rootPath()))
# clicked.CONNECT
self.treeView.clicked.connect(self.treeClicked)
self.treeView.show()
def treeClicked(self, checked=False):
# EMIT
self.tree_model_indexSig.emit(self.model.index(QDir.rootPath()))
# Definition des slots
def indexSlot(self, *args):
# 1 argument --> ModelIndex
path = QDirModel(args[0]).filePath(args[0].currentIndex())
print path
'''
How get the path from the selected file ??
'''
if __name__=='__main__':
app = QApplication(sys.argv)
widget = MyWidget()
widget.show()
app.exec_()
Thanks for help!
Something like this should work for you:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
from PyQt4 import QtCore, QtGui
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pathRoot = QtCore.QDir.rootPath()
self.model = QtGui.QFileSystemModel(self)
self.model.setRootPath(self.pathRoot)
self.indexRoot = self.model.index(self.model.rootPath())
self.treeView = QtGui.QTreeView(self)
self.treeView.setModel(self.model)
self.treeView.setRootIndex(self.indexRoot)
self.treeView.clicked.connect(self.on_treeView_clicked)
self.labelFileName = QtGui.QLabel(self)
self.labelFileName.setText("File Name:")
self.lineEditFileName = QtGui.QLineEdit(self)
self.labelFilePath = QtGui.QLabel(self)
self.labelFilePath.setText("File Path:")
self.lineEditFilePath = QtGui.QLineEdit(self)
self.gridLayout = QtGui.QGridLayout()
self.gridLayout.addWidget(self.labelFileName, 0, 0)
self.gridLayout.addWidget(self.lineEditFileName, 0, 1)
self.gridLayout.addWidget(self.labelFilePath, 1, 0)
self.gridLayout.addWidget(self.lineEditFilePath, 1, 1)
self.layout = QtGui.QVBoxLayout(self)
self.layout.addLayout(self.gridLayout)
self.layout.addWidget(self.treeView)
#QtCore.pyqtSlot(QtCore.QModelIndex)
def on_treeView_clicked(self, index):
indexItem = self.model.index(index.row(), 0, index.parent())
fileName = self.model.fileName(indexItem)
filePath = self.model.filePath(indexItem)
self.lineEditFileName.setText(fileName)
self.lineEditFilePath.setText(filePath)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.resize(666, 333)
main.move(app.desktop().screen().rect().center() - main.rect().center())
main.show()
sys.exit(app.exec_())
Related
I am trying to print text into QTextEdit field but for some reason the image shows up first.
Here is my code:
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
textEdit = QtGui.QTextEdit('',self)
textEdit.setGeometry(QtCore.QRect(300, 300, 640, 480))
textEdit.move(0, 0)
self.setGeometry(300, 300, 640, 480)
img = QImage('image.png','PNG')
cursor = QTextCursor(textEdit.document())
cursor.insertText("Hello World")
cursor.insertImage(img)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
It looks like this in my QTextEdit field:
some image
Hello World
But I want it to look like:
Hello World
some image
The image is on top of the string. Also, there's a big ugly cursor as tall as my image (500 pixels high). What code should I use so a) the string prints before the image and b) the cursor is hidden after I'm done inserting?
You'll need to position the cursor where you want to insert the image. Checkout this code:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtGui, QtCore
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonImage = QtGui.QPushButton(self)
self.pushButtonImage.setText("Insert Image!")
self.pushButtonImage.clicked.connect(self.on_pushButtonImage_clicked)
self.textEditImage = QtGui.QTextEdit(self)
self.textEditImage.setPlainText("Insert an image here:")
self.layoutVertical = QtGui.QVBoxLayout(self)
self.layoutVertical.addWidget(self.pushButtonImage)
self.layoutVertical.addWidget(self.textEditImage)
def on_pushButtonImage_clicked(self):
filePath = QtGui.QFileDialog.getOpenFileName(
self,
"Select an image",
".",
"Image Files(*.png *.gif *.jpg *jpeg *.bmp)"
)
if not filePath.isEmpty():
self.insertImage(filePath)
def insertImage(self, filePath):
imageUri = QtCore.QUrl(QtCore.QString("file://{0}".format(filePath)))
image = QtGui.QImage(QtGui.QImageReader(filePath).read())
self.textEditImage.document().addResource(
QtGui.QTextDocument.ImageResource,
imageUri,
QtCore.QVariant(image)
)
imageFormat = QtGui.QTextImageFormat()
imageFormat.setWidth(image.width())
imageFormat.setHeight(image.height())
imageFormat.setName(imageUri.toString())
textCursor = self.textEditImage.textCursor()
textCursor.movePosition(
QtGui.QTextCursor.End,
QtGui.QTextCursor.MoveAnchor
)
textCursor.insertImage(imageFormat)
# This will hide the cursor
blankCursor = QtGui.QCursor(QtCore.Qt.BlankCursor)
self.textEditImage.setCursor(blankCursor)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
layout
layout (1)
QlineEdit
Qpushbutton
layout (2)
QlineEdit
Qpushbutton
Qpushbutton (3)
I try to create and delete layout(1,2) in layout.
it's work real time. layout(1,2) are dynamic number (1,2,3,~~)
Qpushbutton click -> parent layout and widget delete
and query text in QlineEdit
my test code --
#-*- coding:utf-8 -*-
import maya.cmds as mc
import os
import pprint
from PySide2 import QtWidgets, QtCore, QtGui
class PreferenceUI(QtWidgets.QDialog):
def __init__(self):
super(PreferenceUI, self).__init__()
self.setWindowTitle("preference")
self.create_widgets()
self.create_layouts()
self.create_connections()
self.load_department()
def create_widgets(self):
self.departmentNameLine = QtWidgets.QLineEdit()
self.departmentNameLine.setFixedSize(100,20)
self.departmentPathLine = QtWidgets.QLineEdit()
self.departmentMinusBtn = QtWidgets.QPushButton("-")
self.departmentMinusBtn.setFixedSize(20,20)
self.departmentPlusBtn = QtWidgets.QPushButton("+")
self.sysAppendWidget = QtWidgets.QTextEdit()
def create_layouts(self):
self.mainLayout = QtWidgets.QFormLayout(self)
self.departmentLayout = QtWidgets.QVBoxLayout()
self.departmentLastLayout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(self.departmentLastLayout)
self.departmentLayout.addWidget(self.departmentPlusBtn)
self.mainLayout.addRow("department :", self.departmentLayout)
self.mainLayout.insertRow(self.mainLayout.count()-1, "sys.path.append :", self.sysAppendWidget)
def create_connections(self):
pass
def load_department(self):
self.departmentPlusBtn.setParent(None)
jsonDict = {"department": [["temp", "tempPath"], ["temp2", "temp2Path"]]}
for i in range(len(jsonDict["department"])):
layout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(layout)
departmentNameLine = QtWidgets.QLineEdit()
departmentNameLine.setText(jsonDict["department"][i][0])
departmentNameLine.setFixedSize(100,20)
departmentPathLine = QtWidgets.QLineEdit()
departmentPathLine.setText(jsonDict["department"][i][1])
departmentMinusBtn = QtWidgets.QPushButton("-")
departmentMinusBtn.setFixedSize(20,20)
cnt = self.departmentLayout.count()
departmentMinusBtn.clicked.connect(lambda x:self.remove_department(cnt))
layout.addWidget(departmentNameLine)
layout.addWidget(departmentPathLine)
layout.addWidget(departmentMinusBtn)
self.departmentLayout.insertWidget(self.departmentLayout.count(), self.departmentPlusBtn)
def remove_department(self, index):
print index
print self.departmentLayout.children()[0].layout().children()
if __name__ == "__main__":
try:
ui.close
except:
pass
ui = PreferenceUI()
ui.show()
I want
add path line
delete path line
query departmentNameLine, departmentPathLine text
i try ↑, but fail
i try in maya
To keep the logic tidy I have created a class that represents a row, then store the rows in a list to get the texts or to delete the row as I show below:
from functools import partial
from PySide2 import QtWidgets, QtCore, QtGui
class Widget(QtWidgets.QWidget):
def __init__(self, text1, text2, parent=None):
super().__init__(parent)
self.departmentNameLine = QtWidgets.QLineEdit(text1)
self.departmentNameLine.setFixedSize(100, 20)
self.departmentPathLine = QtWidgets.QLineEdit(text2)
self.departmentMinusBtn = QtWidgets.QPushButton("-")
self.departmentMinusBtn.setFixedSize(20, 20)
self.setContentsMargins(0, 0, 0, 0)
layout = QtWidgets.QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.departmentNameLine)
layout.addWidget(self.departmentPathLine)
layout.addWidget(self.departmentMinusBtn)
class PreferenceUI(QtWidgets.QDialog):
def __init__(self):
super(PreferenceUI, self).__init__()
self.widgets = []
self.setWindowTitle("preference")
self.create_widgets()
self.create_layouts()
self.create_connections()
self.load_department()
def create_widgets(self):
self.departmentPlusBtn = QtWidgets.QPushButton("+")
self.sysAppendWidget = QtWidgets.QTextEdit()
def create_layouts(self):
self.mainLayout = QtWidgets.QFormLayout(self)
self.departmentLayout = QtWidgets.QVBoxLayout()
self.departmentLastLayout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(self.departmentLastLayout)
self.departmentLayout.addWidget(self.departmentPlusBtn)
self.mainLayout.addRow("department :", self.departmentLayout)
self.mainLayout.insertRow(
self.mainLayout.count() - 1, "sys.path.append :", self.sysAppendWidget
)
def create_connections(self):
self.departmentPlusBtn.clicked.connect(self.add_row)
def load_department(self):
jsonDict = {"department": [["temp", "tempPath"], ["temp2", "temp2Path"]]}
for text1, text2 in jsonDict["department"]:
self.create_row(text1, text2)
def save_departament(self):
l = []
for widget in self.widgets:
l.append([self.departmentNameLine.text(), self.departmentPathLine.text()])
jsonDict = {"department": l}
print(jsonDict)
def add_row(self):
self.create_row("text1", "text2")
def create_row(self, text1="", text2=""):
widget = Widget(text1, text2)
widget.departmentMinusBtn.clicked.connect(partial(self.delete, widget))
self.departmentLayout.addWidget(widget)
self.widgets.append(widget)
def delete(self, widget):
if widget in self.widgets:
self.widgets.remove(widget)
widget.deleteLater()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = PreferenceUI()
w.show()
sys.exit(app.exec_())
How can I make the spinner that is right-clicked have it's value changed to the minimum value of that particular QSpinBox? This should work for each spinner in this UI. So the top spinner's value would change to 1 when right-clicked and the bottom spinners value would change to 0 when that spinner is right-clicked.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import math
from PySide import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
#ESTIMATED TOTAL RENDER TIME
self.spinFrameCountA = QtGui.QSpinBox()
self.spinFrameCountA.setRange(1,999999)
self.spinFrameCountA.setValue(40)
self.spinFrameCountB = QtGui.QSpinBox()
self.spinFrameCountB.setRange(0,999999)
self.spinFrameCountB.setValue(6)
# UI LAYOUT
grid = QtGui.QGridLayout()
grid.setSpacing(0)
grid.addWidget(self.spinFrameCountA, 0, 0, 1, 1)
grid.addWidget(self.spinFrameCountB, 1, 0, 1, 1)
self.setLayout(grid)
self.setGeometry(800, 400, 100, 50)
self.setWindowTitle('Render Time Calculator')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Here's how to add a an item to the default context-menu that should do what you want:
...
self.spinFrameCountA = QtGui.QSpinBox()
self.spinFrameCountA.setRange(1,999999)
self.spinFrameCountA.setValue(40)
self.spinFrameCountA.installEventFilter(self)
self.spinFrameCountB = QtGui.QSpinBox()
self.spinFrameCountB.setRange(0,999999)
self.spinFrameCountB.setValue(6)
self.spinFrameCountB.installEventFilter(self)
...
def eventFilter(self, widget, event):
if (event.type() == QtCore.QEvent.ContextMenu and
isinstance(widget, QtGui.QSpinBox)):
menu = widget.lineEdit().createStandardContextMenu()
menu.addSeparator()
menu.addAction('Reset Value',
lambda: widget.setValue(widget.minimum()))
menu.exec_(event.globalPos())
menu.deleteLater()
return True
return QtGui.QWidget.eventFilter(self, widget, event)
I have a QVBoxLayout where I put some buttons. I wrote a function to remove a button, but when I do it, the box doesn't adapt its size to the content.
Here is a piece of the removal function:
for each_difference in differences_remove:
old_index = self.all_tags.index(each_difference)
print("old" + str(old_index))
self.vbox_all_tags.removeWidget(self.liste_pressoirs[old_index])
del self.liste_pressoirs[old_index]
I would like self.vbox_all_tags to adapt its size to the new content after I remove a button. How would you do that ?
Kindly.
Just call adjustSize on your widget after removing the button, here is a demonstration:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtCore, QtGui
class MyWindow(QtGui.QWidget):
_buttons = []
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonRemove = QtGui.QPushButton(self)
self.pushButtonRemove.setText("Remove A Button!")
self.pushButtonRemove.clicked.connect(self.on_pushButtonRemove_clicked)
self.widgetButtons = QtGui.QWidget(self)
self.layoutButtons = QtGui.QHBoxLayout(self.widgetButtons)
self.layout = QtGui.QVBoxLayout(self)
self.layout.addWidget(self.pushButtonRemove)
self.layout.addWidget(self.widgetButtons)
for buttonNumber in range(3):
pushButton = QtGui.QPushButton()
pushButton.setText("Button {0}".format(buttonNumber))
self._buttons.append(pushButton)
self.layoutButtons.addWidget(pushButton)
#QtCore.pyqtSlot()
def on_pushButtonRemove_clicked(self):
if self._buttons:
pushButton = self._buttons[-1]
self._buttons.pop()
self.layoutButtons.removeWidget(pushButton)
pushButton.deleteLater()
self.widgetButtons.adjustSize()
self.adjustSize()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
I want to preview, and then print, a report through a printer using PyQt. I tried the following code :
printer = QtGui.QPrinter()
doc = QtGui.QTextDocument("testing")
dialog = QtGui.QPrintDialog(printer)
dialog.setModal(True)
dialog.setWindowTitle("printerrr")
pdialog = QtGui.QPrintPreviewDialog(printer)
pdialog.setWindowFlags(QtCore.Qt.Window)
pdialog.exec_()
How I can preview my report then print it?
Basic demo of Qt's print dialogs:
PyQt4
import sys, os
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setWindowTitle('Document Printer')
self.editor = QtGui.QTextEdit(self)
self.editor.textChanged.connect(self.handleTextChanged)
self.buttonOpen = QtGui.QPushButton('Open', self)
self.buttonOpen.clicked.connect(self.handleOpen)
self.buttonPrint = QtGui.QPushButton('Print', self)
self.buttonPrint.clicked.connect(self.handlePrint)
self.buttonPreview = QtGui.QPushButton('Preview', self)
self.buttonPreview.clicked.connect(self.handlePreview)
layout = QtGui.QGridLayout(self)
layout.addWidget(self.editor, 0, 0, 1, 3)
layout.addWidget(self.buttonOpen, 1, 0)
layout.addWidget(self.buttonPrint, 1, 1)
layout.addWidget(self.buttonPreview, 1, 2)
self.handleTextChanged()
def handleOpen(self):
path = QtGui.QFileDialog.getOpenFileName(
self, 'Open file', '',
'HTML files (*.html);;Text files (*.txt)')
if path:
file = QtCore.QFile(path)
if file.open(QtCore.QIODevice.ReadOnly):
stream = QtCore.QTextStream(file)
text = stream.readAll()
info = QtCore.QFileInfo(path)
if info.completeSuffix() == 'html':
self.editor.setHtml(text)
else:
self.editor.setPlainText(text)
file.close()
def handlePrint(self):
dialog = QtGui.QPrintDialog()
if dialog.exec_() == QtGui.QDialog.Accepted:
self.editor.document().print_(dialog.printer())
def handlePreview(self):
dialog = QtGui.QPrintPreviewDialog()
dialog.paintRequested.connect(self.editor.print_)
dialog.exec_()
def handleTextChanged(self):
enable = not self.editor.document().isEmpty()
self.buttonPrint.setEnabled(enable)
self.buttonPreview.setEnabled(enable)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
PyQt5
import sys, os
from PyQt5 import QtCore, QtWidgets, QtPrintSupport
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setWindowTitle('Document Printer')
self.editor = QtWidgets.QTextEdit(self)
self.editor.textChanged.connect(self.handleTextChanged)
self.buttonOpen = QtWidgets.QPushButton('Open', self)
self.buttonOpen.clicked.connect(self.handleOpen)
self.buttonPrint = QtWidgets.QPushButton('Print', self)
self.buttonPrint.clicked.connect(self.handlePrint)
self.buttonPreview = QtWidgets.QPushButton('Preview', self)
self.buttonPreview.clicked.connect(self.handlePreview)
layout = QtWidgets.QGridLayout(self)
layout.addWidget(self.editor, 0, 0, 1, 3)
layout.addWidget(self.buttonOpen, 1, 0)
layout.addWidget(self.buttonPrint, 1, 1)
layout.addWidget(self.buttonPreview, 1, 2)
self.handleTextChanged()
def handleOpen(self):
path = QtWidgets.QFileDialog.getOpenFileName(
self, 'Open file', '',
'HTML files (*.html);;Text files (*.txt)')[0]
if path:
file = QtCore.QFile(path)
if file.open(QtCore.QIODevice.ReadOnly):
stream = QtCore.QTextStream(file)
text = stream.readAll()
info = QtCore.QFileInfo(path)
if info.completeSuffix() == 'html':
self.editor.setHtml(text)
else:
self.editor.setPlainText(text)
file.close()
def handlePrint(self):
dialog = QtPrintSupport.QPrintDialog()
if dialog.exec_() == QtWidgets.QDialog.Accepted:
self.editor.document().print_(dialog.printer())
def handlePreview(self):
dialog = QtPrintSupport.QPrintPreviewDialog()
dialog.paintRequested.connect(self.editor.print_)
dialog.exec_()
def handleTextChanged(self):
enable = not self.editor.document().isEmpty()
self.buttonPrint.setEnabled(enable)
self.buttonPreview.setEnabled(enable)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
EDIT
To print-preview a graphics view, use its render method:
def handlePreview(self):
# dialog = QtPrintSupport.QPrintPreviewDialog() # PyQt5
dialog = QtGui.QPrintPreviewDialog()
dialog.paintRequested.connect(self.handlePaintRequest)
dialog.exec_()
def handlePaintRequest(self, printer):
self.view.render(QtGui.QPainter(printer))
A PyQt5 update to the example by ekhumoro providing print preview and print for a Chart:
from PyQt5 import QtChart, QtCore, QtGui, QtPrintSupport, QtWidgets
import sys
import random
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle(self.tr('Chart Printing'))
self.chart = QtChart.QChart()
self.chart_view = QtChart.QChartView(self.chart)
self.chart_view.setRenderHint(QtGui.QPainter.Antialiasing)
self.buttonPreview = QtWidgets.QPushButton('Preview', self)
self.buttonPreview.clicked.connect(self.handle_preview)
self.buttonPrint = QtWidgets.QPushButton('Print', self)
self.buttonPrint.clicked.connect(self.handle_print)
layout = QtWidgets.QGridLayout(self)
layout.addWidget(self.chart_view, 0, 0, 1, 2)
layout.addWidget(self.buttonPreview, 1, 0)
layout.addWidget(self.buttonPrint, 1, 1)
self.create_chart()
def create_chart(self):
self.chart.setTitle("Chart Print Preview and Print Example")
for i in range(5):
series = QtChart.QLineSeries()
series.setName("Line {}".format(i + 1))
series.append(0, 0)
for i in range(1, 10):
series.append(i, random.randint(1, 9))
series.append(10, 10)
self.chart.addSeries(series)
self.chart.createDefaultAxes()
def handle_print(self):
printer = QtPrintSupport.QPrinter(QtPrintSupport.QPrinter.HighResolution)
dialog = QtPrintSupport.QPrintDialog(printer, self)
if dialog.exec_() == QtPrintSupport.QPrintDialog.Accepted:
self.handle_paint_request(printer)
def handle_preview(self):
dialog = QtPrintSupport.QPrintPreviewDialog()
dialog.paintRequested.connect(self.handle_paint_request)
dialog.exec_()
def handle_paint_request(self, printer):
painter = QtGui.QPainter(printer)
painter.setViewport(self.chart_view.rect())
painter.setWindow(self.chart_view.rect())
self.chart_view.render(painter)
painter.end()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
Edit: For the above demo code to run on Windows, then it requires:
> pip install PyQt5
> pip install pyqt5-tools
> pip install PyQtChart