I am trying to make a simple interface using Pyside that will accept and write text to a csv file.
The code below doesn't produce an error message but it will only write things like "PySide.QtGui.QLineEdit object at 0x03A534B8" to the csv file. I have been trying to work out how to set these as strings but am stuck (I have minimal experience with python and pyside). What am I doing wrong?
import sys
from PySide import QtGui, QtCore
import csv
class Form(QtGui.QWidget):
def __init__(self):
super(Form, self).__init__()
self.initUI()
def initUI(self):
global itemText
global descText
item = QtGui.QLabel('Item')
itemEdit = QtGui.QLineEdit()
itemText = str(itemEdit)
desc = QtGui.QLabel('Description (optional)')
descEdit = QtGui.QTextEdit()
descText = str(descEdit)
add = QtGui.QPushButton("Add item")
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(item, 1, 0)
grid.addWidget(itemEdit, 1, 1)
grid.addWidget(desc, 2, 0)
grid.addWidget(descEdit, 2, 1, 3, 1)
grid.addWidget(add, 6, 1)
add.clicked.connect(self.writeFile)
self.setLayout(grid)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle("Add to list")
self.show()
def writeFile(self):
csvfile = open('list.csv', 'ab')
csvwriter = csv.writer(csvfile)
csvwriter.writerow([itemText, descText])
print itemText
def main():
app = QtGui.QApplication(sys.argv)
ex = Form()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Try changing this line
descText = str(descEdit)
for this:
descText = str(descEdit.text())
Related
According to the following table and the code which I constructed as an example, I require a proper code & table from which we can obtain the values of the 'Quantity' & 'Rate'(price) to be displayed as 'Subtotal' (Subtotal = Quantity * Rate). Its little bit confusing to understand the exact logic here.
here my code is given bellow:
from PyQt4 import QtGui, QtCore
import sys
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self. table = QtGui.QTableWidget(self)
self.table.move(10,70)
self.table.resize(500,300)
self.table_item = QtGui.QTableWidgetItem()
self.table.setRowCount(3)
self.table.verticalHeader().hide()
self.table.setColumnCount(6)
self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.fnt = self.table.font()
self.fnt.setPointSize(11)
self.table.setFont(self.fnt)
self.table.setHorizontalHeaderLabels(("S.no, Item Description,Qty,Rate(Rs:),Subtotal,"",").split(','))
self.table.setItem(0,0,QtGui.QTableWidgetItem("1"))
self.table.setItem(0,1, QtGui.QTableWidgetItem("Acne-aid Wash Facial Cleansing"))
self.table.setItem(0,3,QtGui.QTableWidgetItem("191.72"))
self.table.setItem(0,5,QtGui.QTableWidgetItem(""))
self.table.setItem(1,1,QtGui.QTableWidgetItem("Moisturizer"))
self.table.setItem(1,3,QtGui.QTableWidgetItem("90"))
self.table.setItem(1,5,QtGui.QTableWidgetItem(""))
self.table.setItem(1,0,QtGui.QTableWidgetItem("2"))
self.table.setItem(2,0,QtGui.QTableWidgetItem("3"))
self.table.setItem(2,1,QtGui.QTableWidgetItem("Brightening eye cream"))
self.table.setItem(2,3,QtGui.QTableWidgetItem("40"))
self.table.setItem(2,5,QtGui.QTableWidgetItem(""))
for x in range(0,4):
self.spin = QtGui.QSpinBox()
self.spin.setMinimum(1)
self.spin.setMaximum(50)
self.table.setCellWidget(x,2,self.spin)
for x in range(0,4):
self.btn = QtGui.QPushButton(self)
self.btn.setIcon(QtGui.QIcon("trash1.png"))
self.table.setCellWidget(x,5,self.btn)
self.setWindowTitle("To do app")
self.setGeometry(200,300,600,300)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The solution is to connect the valueChanged signal of the QSpinBox to any slot where the calculated is done, that signal sends the information of the current value but does not indicate the row to which the QSpinBox belongs. For this we use functool.partial to indicate the row (another option is to use a lambda function).
On the other hand I have improved your code, I see that you abuse self, for example in a for-loop the variables that are created inside must not be created using self. Also I have reduced the code with which you create the data.
import sys
from functools import partial
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self. table = QtGui.QTableWidget(3, 6, self)
self.table.setGeometry(10, 70, 500,300)
self.table.verticalHeader().hide()
self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
fnt = self.table.font()
fnt.setPointSize(11)
self.table.setFont(fnt)
self.table.setHorizontalHeaderLabels(("S.no, Item Description,Qty,Rate(Rs:),Subtotal,"",").split(','))
all_data = [("1", "Acne-aid Wash Facial Cleansing", 191.72, 0),
("2", "AMoisturizer", 90, 0),
("3", "Brightening eye cream", 40, 0)]
for r, row_data in enumerate(all_data):
for c, value in zip((0, 1, 3, 4), row_data):
it = QtGui.QTableWidgetItem(str(value))
self.table.setItem(r, c, it)
for r in range(self.table.rowCount()):
spin = QtGui.QSpinBox(minimum=0, maximum=50)
spin.valueChanged.connect(partial(self.calculateSubTotal, r))
self.table.setCellWidget(r, 2, spin)
btn = QtGui.QPushButton(icon=QtGui.QIcon("trash1.png"))
self.table.setCellWidget(r, 5, btn)
self.setWindowTitle("To do app")
self.setGeometry(200, 300, 600, 300)
self.show()
def calculateSubTotal(self, row, value):
rate = float(self.table.item(row, 3).text())
subtotal = value * rate
item_subtotal = self.table.item(row, 4)
if item_subtotal is None:
item_subtotal = QtGui.QTableWidgetItem()
self.table.setItem(row, 4, item_subtotal)
item_subtotal.setText(str(subtotal))
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I am trying to figure out a way to save the current state and all values in the gui such as the text in QLineEdit and QEditText widgets.
I found this code which I have been trying to use and it seems that I can get it to save everything okay when I exit the GUI but when I open it, all it seems to restore is the window dimensions if I had moved them previously.
I can see in the ini file that everything gets saved including any text in the 2 widgets but I cant get the text to restore when I open the GUI. Does anyone know how I can get the text values to restore as well?
Here is what I am currently working with.
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def restore(settings):
finfo = QFileInfo(settings.fileName())
if finfo.exists() and finfo.isFile():
for w in qApp.allWidgets():
mo = w.metaObject()
if w.objectName() != "":
for i in range(mo.propertyCount()):
name = mo.property(i).name()
val = settings.value("{}/{}".format(w.objectName(), name), w.property(name))
w.setProperty(name, val)
def save(settings):
for w in qApp.allWidgets():
mo = w.metaObject()
if w.objectName() != "":
for i in range(mo.propertyCount()):
name = mo.property(i).name()
settings.setValue("{}/{}".format(w.objectName(), name), w.property(name))
class MainWindow(QWidget):
settings = QSettings("gui.ini", QSettings.IniFormat)
def __init__(self):
super(MainWindow, self).__init__()
self.setObjectName("MainWindow")
restore(self.settings)
self.layout = QGridLayout()
self.text_Box = QTextEdit(self)
self.text_Box.setObjectName("text_Box")
self.layout.addWidget(self.text_Box, 2, 0, 1, 1)
self.quit_Button = QPushButton(self)
self.quit_Button.setMaximumSize(30, 30)
self.quit_Button.setObjectName("quit_Button")
self.layout.addWidget(self.quit_Button, 3, 0, 1, 1)
self.line_Edit = QLineEdit(self)
self.line_Edit.setObjectName("line_Edit")
self.layout.addWidget(self.line_Edit, 1, 0, 1, 1)
self.quit_Button.clicked.connect(self.exitGUI)
self.setLayout(self.layout)
def closeEvent(self, event):
save(self.settings)
QWidget.closeEvent(self, event)
def exitGUI(self):
self.close()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()
sys.exit(app.exec_())
I want to be able to add timestamps to a QListWidget instance and save this to a textfile. As well as view the items already in the textfile so the items are saved after program exit.
The code I have at the moment saves it to the list as I want to, but I do not see the items I added before closing and reopening the program:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from datetime import datetime
class feedingTime(QDialog):
def __init__(self):
QDialog.__init__(self)
layout = QVBoxLayout()
self.feedList = QListWidget()
self.label = QLabel(datetime.now().strftime('%Y-%m-%d %H:%M:%S'),self)
self.button = QPushButton("Add time")
self.info = QLabel("Baby was last fed:")
layout.addWidget(self.label)
layout.addWidget(self.button)
layout.addWidget(self.info)
layout.addWidget(self.feedList)
self.setLayout(layout)
self.timer = QTimer(self.label)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.displayTime)
self.timer.start()
self.button.clicked.connect(self.feedAdd)
def feedAdd(self):
self.feedList.addItem(self.label.text())
def displayTime(self):
self.label.setText(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
if __name__ == "__main__":
app = QApplication(sys.argv)
dialog = feedingTime()
dialog.show()
sys.exit(app.exec_())
Is there and easy way to read list from textfile as well as appending new timestamps when button is pressed? It would also be nice to add a button that removes the "oldest" timestamp when clicked.
Im trying to make a brestfeeding app for my wife :)
PyQt noob here. Thanks for the help.
Saving data to a log has nothing to do with PyQt. All you need is basic knowledge of working with I/O in Python. I used simple log file which must be located in same directory as the script does (could be improved to something more sophisticated). I implemented also desired delete button, however, I'm not sure if I correctly understood meaning of "oldest" timestamp.
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from datetime import datetime
FILENAME = "history.log"
class feedingTime(QDialog):
def __init__(self):
QDialog.__init__(self)
layout = QVBoxLayout()
self.feedList = QListWidget()
self.label = QLabel(datetime.now().strftime('%Y-%m-%d %H:%M:%S'),self)
self.button = QPushButton("Add time")
self.info = QLabel("Baby was last fed:")
self.buttonDelete = QPushButton("Delete oldest")
layout.addWidget(self.label)
layout.addWidget(self.button)
layout.addWidget(self.info)
layout.addWidget(self.feedList)
layout.addWidget(self.buttonDelete)
self.setLayout(layout)
self.timer = QTimer(self.label)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.displayTime)
self.timer.start()
self.button.clicked.connect(self.feedAdd)
self.buttonDelete.clicked.connect(self.deleteOldest)
self.loadOldData()
def deleteOldest(self):
self.feedList.takeItem(self.feedList.count() - 1)
lines = open(FILENAME).readlines()
with open(FILENAME, 'w') as f:
f.writelines(lines[1:])
def feedAdd(self):
date = self.label.text()
self.feedList.addItem(date)
f = open(FILENAME, 'a')
f.write(date + '\n')
f.close()
self.feedList.sortItems(Qt.DescendingOrder) # change to AscendingOrder if want inverted order
def fillData(self, lines):
for line in lines:
self.feedList.addItem(line.rstrip())
def loadOldData(self):
try:
file = open(FILENAME)
lines = file.readlines()
self.fillData(lines)
except IOError:
print "File" + FILENAME + "not found, skipping..."
def displayTime(self):
self.label.setText(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
if __name__ == "__main__":
app = QApplication(sys.argv)
dialog = feedingTime()
dialog.show()
sys.exit(app.exec_())
I am developing an app using PyQt4. And I would like to have an option to print the main widget to a pdf document. I have a custom qlayout for the main widget and I want to create a pdf document with that qlayout. I read a lot about pyqt qprinter, but I'm not sure that's what I want.
Could anyone suggest how I could create a pdf with a qlayout full of qwidgets?
Use QPixmap.grabWidget to render the widget to a pixmap, then paint that on a QPrinter which can then convert it to a pdf:
import sys
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.text = QtGui.QTextEdit(self)
self.text.setText(open(__file__).read())
self.edit = QtGui.QLineEdit(self)
self.edit.setText('/tmp/test.pdf')
self.buttonSave = QtGui.QPushButton('Save', self)
self.buttonSave.clicked.connect(self.handleSave)
layout = QtGui.QGridLayout(self)
layout.addWidget(self.text, 0, 0, 1, 2)
layout.addWidget(self.edit, 1, 0, 1, 1)
layout.addWidget(self.buttonSave, 1, 1, 1, 1)
def handleSave(self):
printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
printer.setPageSize(QtGui.QPrinter.A6)
printer.setColorMode(QtGui.QPrinter.Color)
printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
printer.setOutputFileName(self.edit.text())
pixmap = QtGui.QPixmap.grabWidget(self).scaled(
printer.pageRect(QtGui.QPrinter.DevicePixel).size().toSize(),
QtCore.Qt.KeepAspectRatio)
painter = QtGui.QPainter(printer)
painter.drawPixmap(0, 0, pixmap)
painter.end()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 640, 640)
window.show()
sys.exit(app.exec_())
EDIT:
If the QPainter part won't work for some reason on your setup, you could try the alternative save method below:
def handleSave(self):
printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
printer.setPageSize(QtGui.QPrinter.A9)
printer.setColorMode(QtGui.QPrinter.Color)
printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
printer.setOutputFileName(self.edit.text())
self.render(printer)
Or another alternative would be to use a QTextDocument:
def handleSave(self):
printer = QtGui.QPrinter()
printer.setPageSize(QtGui.QPrinter.A5)
printer.setResolution(200)
printer.setColorMode(QtGui.QPrinter.Color)
printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
printer.setOutputFileName(self.edit.text())
size = printer.pageRect(QtGui.QPrinter.DevicePixel).size()
pixmap = QtGui.QPixmap.grabWidget(self).scaled(
size.toSize(), QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
data = QtCore.QByteArray()
buffer = QtCore.QBuffer(data)
pixmap.save(buffer, 'PNG')
document = QtGui.QTextDocument()
document.setPageSize(size)
document.setHtml('<img src="data:image/png;base64,%s"/>' %
bytes(data.toBase64()).decode('ascii'))
document.print_(printer)
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_())