I have a new question, I am designing an application and I don not know how to export items to an excel file, in the code I use a QTreeView with a QSortFilteredProxyModel, and I include a filter for text written in a QLineEdit, I need to export all of the items than can be seen after being filtered. But, how can i take or add those items to a list, for exporting them to an excel file?
if anyone can help me I would be so grateful.
sry my bad english
# -*- coding: utf-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from dbFacades.profitFacade import ProfitFacade
class MainTabProfits(QGridLayout):
def __init__(self):
super(MainTabProfits, self).__init__()
self.screen = QDesktopWidget().screenGeometry()
self.profitList = ProfitFacade().allProfit()
self.addWidget(self.topGroupBox(),0,0,1,4)
self.addWidget(self.rightGroupBox(), 1, 0,1,4)
self.addWidget(self.botGroupBox(),2,3)
# -----------------------------------------------------
# Se define el grupo superior
def topGroupBox(self):
groupBox = QGroupBox()
groupBox.setTitle("Busqueda")
self.lineEdit1 = QLineEdit()
self.lineEdit1.setPlaceholderText("Ingrese una fecha con el siguiente formato -> dd/mm/aaaa")
self.lineEdit1.textChanged.connect(self.filterRegExpChanged)
self.lineEdit1.textChanged.connect(self.setSlashChanged)
self.lineEdit1.setMaxLength(10)
leftLayout = QHBoxLayout()
leftLayout.addWidget(self.lineEdit1)
leftLayout.stretch(1)
leftGroupBox = QGroupBox("Fecha Exacta")
leftGroupBox.setLayout(leftLayout)
hBoxLayout = QHBoxLayout()
hBoxLayout.addWidget(leftGroupBox)
groupBox.setLayout(hBoxLayout)
return groupBox
# -----------------------------------------------------
# Se define el grupo principal(izquierdo) de contenido
def rightGroupBox(self):
groupBox = QGroupBox()
groupBox.setTitle("Control de Finanzas y busqueda")
self.setHeaders()
self.proxyModel = QSortFilterProxyModel()
self.proxyModel.setDynamicSortFilter(True)
self.proxyModel.setSourceModel(self.model)
self.proxyModel.setFilterKeyColumn(0)
self.treeView = QTreeView()
self.treeView.setRootIsDecorated(False)
self.treeView.setAlternatingRowColors(True)
self.treeView.setModel(self.proxyModel)
self.treeView.setSortingEnabled(True)
self.treeView.sortByColumn(0, Qt.AscendingOrder)
self.treeView.resizeColumnToContents(0)
self.treeView.setEditTriggers(QTreeView.NoEditTriggers)
vBoxLayout = QVBoxLayout()
vBoxLayout.addWidget(self.treeView)
groupBox.setLayout(vBoxLayout)
self.setProfit()
return groupBox
def botGroupBox(self):
groupBox = QGroupBox()
groupBox.setTitle("Exportacion")
self.radioButton0 = QRadioButton("*.PDF")
self.radioButton0.setIcon(QIcon("icons/pdf.png"))
self.radioButton0.setIconSize(QSize(self.screen.width() / 50, self.screen.width() / 50))
self.radioButton1 = QRadioButton("*.Excel")
self.radioButton1.setIcon(QIcon("icons/excel.png"))
self.radioButton1.setIconSize(QSize(self.screen.width() / 50, self.screen.width() / 50))
pushButton = QPushButton(QIcon("icons/export.png"),"Exportar")
pushButton.released.connect(self.exportList)
pushButton.setIconSize(QSize(self.screen.width() / 50, self.screen.width() / 50))
hBoxLayout = QHBoxLayout()
hBoxLayout.addWidget(self.radioButton0)
hBoxLayout.addWidget(self.radioButton1)
hBoxLayout.addWidget(pushButton)
hBoxLayout.stretch(1)
groupBox.setLayout(hBoxLayout)
return groupBox
# ------------------------------------------------------
# ZONA METODOS
# Metodo que define las cabezeras del menu y crea el model
def setHeaders(self):
self.model = QStandardItemModel(0, 5, self)
self.model.setHeaderData(0, Qt.Horizontal, "Fecha")
self.model.setHeaderData(1, Qt.Horizontal, "Monto")
self.model.setHeaderData(2, Qt.Horizontal, "Mesa")
self.model.setHeaderData(3, Qt.Horizontal, "Tipo de Pago")
self.model.setHeaderData(4, Qt.Horizontal, "Codigo Operacion")
# Metodo para filtrar por texto escrito en line edit
def filterRegExpChanged(self):
regExp = QRegExp(self.lineEdit1.text(), Qt.CaseInsensitive)
self.proxyModel.setFilterRegExp(regExp)
# Metodo para el formato de fecha en LineEdit1
def setSlashChanged(self):
text = self.lineEdit1.text()
if(len(text)==2):
self.lineEdit1.setText(text+"-")
elif(len(text)==5):
self.lineEdit1.setText(text+"-")
self.lineEdit2.setText("")
self.lineEdit3.setText("")
# Metodo para el formato de fecha en lineEdit2 y 2
def inRangeChanged(self):
text = self.lineEdit2.text()
text1 = self.lineEdit3.text()
if(len(text)==2):
self.lineEdit2.setText(text+"-")
elif(len(text)==5):
self.lineEdit2.setText(text+"-")
elif(len(text1)==2):
self.lineEdit3.setText(text1+"-")
elif(len(text1)==5):
self.lineEdit3.setText(text1+"-")
self.lineEdit1.setText("")
# --------------------------------------------------------------------------------
# Metodo que establece los datos en la lista
def setProfit(self):
for profit in self.profitList:
self.model.insertRow(0)
self.model.setData(self.model.index(0,0), profit[0])
self.model.setData(self.model.index(0,1), profit[1])
self.model.setData(self.model.index(0,2), profit[2])
self.model.setData(self.model.index(0,3), profit[3])
self.model.setData(self.model.index(0,4), profit[4])
# --------------------------------------------------------------------------------
# Metodo para exportar a excel
def exportList(self):
if self.radioButton0.isChecked():
pass
if self.radioButton1.isChecked():
HERE I WANT EXPORT ITEMS FILTERED
HERE I WANT EXPORT ITEMS FILTERED
HERE I WANT EXPORT ITEMS FILTERED
HERE I WANT EXPORT ITEMS FILTERED
You can use the fallowing functions from QSortFilterProxyModel:
rowCount(), columnCount() and index(), and then use the returned index to get the data:
rowCnt = self.proxyModel.rowCount()
colCnt = self.proxyModel.columnCount()
for row in range(0, rowCnt):
for col in range(0, colCnt):
modelIndex = self.proxyModel.index(row, col)
print modelIndex.data().toString()
Related
Going straight to the point: I would like to click on the MDFilRoundFlatButton button in the ContentButton class and execute the close_order function in the TelaClose class
Can anyone help me on this one?
I'm still a little confused about executing functions from other classes, especially with kivy.
I've come a long way in this matter, I could use root.get_screen(... but I get an error saying that my class doesn't have the object to be executed.
from kivy.utils import get_color_from_hex
from kivymd.uix.button import MDRoundFlatIconButton
from kivymd.color_definitions import colors
from kivymd.uix.button import MDFillRoundFlatButton, MDRaisedButton
from kivymd.font_definitions import theme_font_styles
from kivymd.uix.label import MDLabel
import json
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd import images_path
from kivymd.uix.expansionpanel import MDExpansionPanel, MDExpansionPanelOneLine
from kivy.uix.screenmanager import Screen
from kivymd.uix.list import (
ImageLeftWidget,
ThreeLineIconListItem,
OneLineListItem,
)
# Imports para trabalhar com Firebase
from config import config
import pyrebase
import requests
from datetime import date
from datetime import datetime
today = date.today()
today_now = datetime.now()
Builder.load_string("""
<Content>
adaptive_height: True
orientation: 'vertical'
# TwoLineIconListItem:
# text: "(050)-123-45-67"
# secondary_text: "Mobile"
#
# IconLeftWidget:
# icon: 'phone'
<ContentButton>
orientation: 'vertical'
adaptive_height: True
MDFillRoundFlatButton:
size_hint: .9, None
pos_hint: {'center_x': .5, 'center_y': .5}
text: "Fechar Pedido"
on_release: root.fechar_pedido()
<TelaFechamento>:
name: 'tela_fechamento'
ScrollView:
pos_hint: {"top": .89}
MDGridLayout:
id: box
cols: 1
adaptive_height: True
""")
class InvoicePanel(MDExpansionPanel):
pass
class Content(MDBoxLayout):
'''Custom content.'''
class ContentButton(MDBoxLayout):
'''Custom content.'''
# Classe criada para permitir alinhamento
class OneLineListItemAligned(OneLineListItem):
def __init__(self, halign, **kwargs):
super(OneLineListItemAligned, self).__init__(**kwargs)
self.ids._lbl_primary.halign = halign
class TelaFechamento(Screen):
def fechar_pedido(self):
# Inicializando o banco de dados.
firebase = pyrebase.initialize_app(config)
db = firebase.database()
app = MDApp.get_running_app()
user_profiles = db.child('UserProfile').child(str(app.logged_user)).get(
token=app.USER_MASTER)
idpedido = {}
# Preenchendo os dados das listas
for produto in user_profiles.each():
if 'Cart' in produto.key():
items = produto.val().get('Cart')
for k, v in items['Opened'].items():
idpedido[k] = v
chave = datetime.now().strftime("%Y%m%d%H%M%S%f")
#print(json.dumps(id_pedido, indent=4))
# ********************************************************************************************************************************
# Criar pedidos importados no WShop
db.child('UserProfile').child(str(app.logged_user)).child(produto.key()).child('Confirmed').child(
chave).set(idpedido, token=app.USER_MASTER)
# Aqui abaixo devo criar o código para excluir de Cart
# Code here, Code here, Code here, .....
def pedidos_abertos(self):
# Inicializando o banco de dados.
firebase = pyrebase.initialize_app(config)
db = firebase.database()
app = MDApp.get_running_app()
json_data = db.child('UserProfile').child(str(app.logged_user)).get(
token=app.USER_MASTER)
for produtos in json_data.each():
#print(json.dumps(produtos.key(), indent=4))
if produtos.key() == 'Cart':
cart = produtos
try:
openeds = cart.val()['Opened']
#print(json.dumps(openeds, indent=4), '...............')
# adicionar fatura como item principal
cw = Content() # preencha o conteúdo à medida que os dados são analisados
ep = InvoicePanel(icon="./images/pedidos/shopping-cart.png", panel_cls=MDExpansionPanelOneLine(text=f'Produtos no carrinho:'),
content=cw)
self.ids.box.add_widget(ep)
# -----------------------------------------------------
# Cria o Widget Especificamente para fechar o pedido.
# close_items = MDRaisedButton(
# text="[color=ffffff]FATURAR ESTES ITENS[/color]", size_hint=(.9, .9))
# cw.add_widget(close_items)
close_items = OneLineListItemAligned(
text='Fechar este pedido agora?',
md_bg_color=app.theme_cls.primary_dark,
halign="center", font_style="H6", on_press=self.fechar_pedido)
# close_items.bind(on_release=print("----------Click!"))
cw.add_widget(close_items)
# -----------------------------------------------------
cw.add_widget(ContentButton())
for key_item, value_item in openeds.items():
#print(json.dumps(key_item, indent=4), '************* key_item')
# Cria a imagem que será usada no TwoLineIconListItem.
image = ImageLeftWidget(
source=value_item['url']
)
# Cria o Widget conforme sua escolha.
items = ThreeLineIconListItem(text=value_item['product_code'],
secondary_text=value_item['product_description'],
tertiary_text='{} x R${} = R${}'.format(value_item['quantidade'], value_item['price'], value_item['total_item']), md_bg_color=get_color_from_hex('#FFFDE7'))
# Adiciona a imagem ao Widget acima.
items.add_widget(image)
cw.add_widget(items)
except:
print('Ainda não possui pedidos!')
def pedidos_faturados(self):
# Inicializando o banco de dados.
firebase = pyrebase.initialize_app(config)
db = firebase.database()
app = MDApp.get_running_app()
json_data = db.child('UserProfile').child(str(app.logged_user)).get(
token=app.USER_MASTER)
for produtos in json_data.each():
#print(json.dumps(produtos.key(), indent=4))
if produtos.key() == 'Cart':
cart = produtos
try:
invoices = cart.val()['Invoice']
for key_invoice, value_invoice in invoices.items():
#print(json.dumps(value_invoice, indent=4))
# adicionar fatura como item principal
cw = Content() # preencha o conteúdo à medida que os dados são analisados
ep = InvoicePanel(icon='./images/pedidos/invoice.png', panel_cls=MDExpansionPanelOneLine(text=f'Confirmado: {key_invoice}'),
content=cw)
self.ids.box.add_widget(ep)
for key_item, value_item in value_invoice.items():
#print(json.dumps(key_item, indent=4))
# Cria a imagem que será usada no TwoLineIconListItem.
image = ImageLeftWidget(
source=value_item['url']
)
# Cria o Widget conforme sua escolha.
items = ThreeLineIconListItem(text=value_item['product_code'],
secondary_text=value_item['product_description'],
tertiary_text='{} x R${} = R${}'.format(value_item['quantidade'], value_item['price'], value_item['total_item']))
# Adiciona a imagem ao Widget acima.
items.add_widget(image)
cw.add_widget(items)
except:
print('Ainda não possui pedidos!')
def on_enter(self):
self.pedidos_abertos()
self.pedidos_faturados()
def on_kv_post(self, base_widget):
app = MDApp.get_running_app()
I think I found the best approach to this.
We must start from the app and go navigating until we reach the window where the class is and after finding execute the function.
<ContentButton>
orientation: 'vertical'
adaptive_height: True
MDFillRoundFlatButton:
size_hint: .9, None
pos_hint: {'center_x': .5, 'center_y': .5}
text: "Fechar Pedido"
on_release: print(app.root.get_screen('main_screen').ids.screen_manager.get_screen('tela_fechamento').fechar_pedido())
I am learning classes. The script below, shows the graph correctly using plotly express, but if I integrate it as a method in a class, it doesn't.
I show the classes below. With the first one, we import quotes from Yahoo! With the second, we try to represent a graph of the imported normalized prices.
import pandas as pd
import pandas_datareader as pdr
import datetime as dt
from datetime import date
from plotly.offline import iplot
import plotly.express as px
class ImportadorCotizaciones:
def __init__(self):
self.cotizaciones = None
self.start = "2000-1-4"
self.end = date.today()
self.cotizaciones = None
def Importar_cotizaciones(self):
dicc_tickers = {"IBE.MC":"Iberdrola", "TEF.MC":"Telefonica", "^IBEX":"Ibex35" }
dfs = []
nombres = []
for (k,v) in dicc_tickers.items():
self.cotizaciones_de_ticker = pdr.DataReader(k, 'yahoo', self.start, self.end)
self.cotizaciones_de_ticker = self.cotizaciones_de_ticker[["Close"]]
self.cotizaciones_de_ticker = self.cotizaciones_de_ticker.rename(columns={"Close": v})
dfs.append(self.cotizaciones_de_ticker)
dfs = iter(dfs)
self.cotizaciones = next(dfs)
for df_ in dfs:
self.cotizaciones = self.cotizaciones.merge(df_, on='Date')
class Indicadores:
def __init__(self, importador):
self.importador = importador
def dibujar_grafico(self):
self.aux_val_ind = importador.cotizaciones[["Iberdrola", "Ibex35"]].pct_change().dropna()
df = self.aux_val_ind.copy(deep=True)
df['Media'] = df.mean(axis = 1)
# Usando plotly.express
px.line((df + 1).cumprod() ,y=df.columns ,title=f"\nValor de 1€ invertido desde el { importador.start} hasta el {importador.end} ")
importador = ImportadorCotizaciones()
importador.Importar_cotizaciones()
importador.cotizaciones[:3]
indicadores = Indicadores(importador)
indicadores.dibujar_grafico()
The script that works outside the class is:
# Usando plotly.express
from plotly.offline import iplot
import plotly.express as px
start = "2000-1-4"
end = date.today()
aux_val_ind = importador.cotizaciones[["Iberdrola", "Ibex35"]].pct_change().dropna()
df = aux_val_ind.copy(deep=True)
df['Media'] = df.mean(axis = 1)
px.line((df + 1).cumprod() ,y=df.columns ,title=f"\nValor actual de 1€ invertido el {start} ")
Only one issue, you missed to return the figure.
class Indicadores:
def __init__(self, importador):
self.importador = importador
def dibujar_grafico(self):
self.aux_val_ind = importador.cotizaciones[["Iberdrola", "Ibex35"]].pct_change().dropna()
df = self.aux_val_ind.copy(deep=True)
df['Media'] = df.mean(axis = 1)
# Usando plotly.express
return px.line((df + 1).cumprod() ,y=df.columns ,title=f"\nValor de 1€ invertido desde el { importador.start} hasta el {importador.end} ")
I am currently working on OCR on pdf files. Here is my pipeline:
i first extract image from pdf (since my pdf contained scanned document) and convert in numpy array
then i read with tesseract
It works pretty well on most of my image but i have sevral whose i can't extract the image inside. I just gave an example and i can't find (see next) the scanned image containing the writing part (for OCR). It drive me crazy (where has it gone ??).
Perhaps you could help me to retrieve that image and understand why my way do not let me retrieve this image "fantôme" ?
NB: i noticed that thoses problematic images inside the pdf are in "jpx" format.
Edit: Since the image is unfindable in the pdf i tried an horrible trick (waiting for clever explanation :) ): converting whole pdf page in pix (PyMuPdf let do that) and then writing the PIX on disk in different format (PNG, TIFF). The quality is too much degraded compared with the original pdf (so we can forget a reasonnable reading with Tesseract).
Here is the pdf example file (if you have simpler hosting way i am curious): https://www.filehosting.org/file/details/906817/IB00058815877D0000000.pdf
Here are the 2 images i extract from the file (the second one should contain txt instead of garbage)
Here is my code to extract images:
import fitz
import os
import logging
import cv2
from PIL import Image
from .utils import lazyproperty,showpdf
from .imhelpers import show
from ..config import myconfig
from impocr import logger
import pytesseract
pytesseract.pytesseract.tesseract_cmd = myconfig.TESSERACT_CMD
class InvalidImage(Exception):
pass
class PDFParser():
"""
"""
def __init__(self,filepath,page_num=0):
self.filepath = filepath
self.filename = os.path.basename(self.filepath).split('.pdf')[0]
try:
self._doc = fitz.open(filepath)
self.page_num = page_num
self._page = self._doc[page_num]
except Exception as e:
print("Lecture PDF impossible. {}".format(e))
raise
#lazyproperty
def text(self):
return self._page.getText()
#lazyproperty
def _pixs(self):
imgs = self._doc.getPageImageList(self.page_num)
pixs =[]
for img in imgs:
xref = img[0]
pix = fitz.Pixmap(self._doc, xref)
pixs.append(pix)
return pixs
#lazyproperty
def _pixpage(self):
pix = self._page.getPixmap(colorspace=fitz.csGRAY)
return pix
#property
def img(self):
return self.imgs[0]
#property
def pageimg(self):
pix = self._pixpage
return self.pix2np(pix)
#lazyproperty
def imgs(self):
pixs = self._pixs
imgsarray = []
for pix in pixs:
img = self.pix2np(pix)
imgsarray.append(img)
return imgsarray
def find_first_valid_image(self):
img_valid = None
for i,img in enumerate(self.imgs):
try:
import ipdb;ipdb.set_trace()
res = pytesseract.image_to_osd(img)
img_valid = img
return img_valid
except pytesseract.TesseractError:
continue
if img_valid==None:
logger.warning('No readable image in page {} of the document {}'.format(self.page_num, self.filename))
raise InvalidImage('No readable image in page {} of the document {}'.format(self.page_num, self.filename))
def write(self,outputdir,fullpage=False):
try:
os.makedirs(outputdir)
logger.info("Directory {} is created".format(outputdir))
except FileExistsError:
pass
def _writepix(pix,filepath):
# This is GRAY or RGB
try:
pix.writePNG(filepath)
# CMYK: convert to RGB first
except:
pix = fitz.Pixmap(fitz.csRGB, pix)
pix.writePNG(filepath)
pix = None
if fullpage:
filepath = os.path.join(outputdir,'{}_p{}.png'.format(self.filename,self.page_num))
pix = self._pixpage
_writepix(pix,filepath)
return
pixs = self._pixs
for i,pix in enumerate(pixs):
filepath = os.path.join(outputdir,'{}_p{}_i{}.png'.format(self.filename,self.page_num,i))
_writepix(pix,filepath)
return
def pix2np(self,pix):
"""
Convert pixmap to image np.ndarray
https://stackoverflow.com/questions/53059007/python-opencv
param pix: pixmap
"""
import numpy as np
#https://stackoverflow.com/questions/22236749/numpy-what-is-the-difference-between-frombuffer-and-fromstring
im = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.h, pix.w, pix.n)
try:
im = np.ascontiguousarray(im[..., [2, 1, 0]]) # rgb to bgr
except IndexError:
#Trick to convert Gray rto BGR, (im.reshape)
#logger.warning("Need to convert Gray to BGR [filepath: {}]".format(self.filepath))
im = cv2.cvtColor(im,cv2.COLOR_GRAY2RGB)
im = np.ascontiguousarray(im[..., [2, 1, 0]])
return im
if __name__ == "__main__":
filepath = r'data\inputs\test\impot_textpdf_with_one_logoimage.pdf'
###### Parse page 0 (first page) ######
pdf = PDFParser(filepath,0)
text = pdf.text
imgs = pdf.imgs
show(pdf.imgs[0])
show(pdf.imgs[1])
############### other functions ####################
class lazyproperty:
def __init__(self, func):
self.func = func
def __get__(self, instance, cls):
if instance is None:
return self
else:
value = self.func(instance)
setattr(instance, self.func.__name__, value)
return value
def show(image):
import matplotlib.pyplot as plt
fig,ax = plt.subplots(1)
ax.imshow(image)
plt.show()
My solution is not so good (but waiting for better ideas but here are my 2 cents idea: i first write the full page and read it with opencv (i changed the method first_valid_image as you can see attached).
from tmpfile import TemporaryDirectory
def find_first_valid_image(self):
#import ipdb;ipdb.set_trace()
img_valid = None
for i,img in enumerate(self.imgs):
try:
#import ipdb;ipdb.set_trace()
res = pytesseract.image_to_osd(img)
img_valid = img
return img_valid
except pytesseract.TesseractError:
continue
if img_valid==None:
logger.warning('No readable image in page {} of the document {}. Tried the fullpage.'.format(self.page_num, self.filename))
with TemporaryDirectory() as tmpdirname:
filepath = self.write(tmpdirname,fullpage=True)
img_fullpage =cv2.imread(filepath)
return img_fullpage
I think it degrade the quality of my original image; so when applying tesseract on the image i got a bad ocr as you can see attached.
"""DIRECTION GÉNÉRALE DE6 FNANCES PUBLIQUES\n\nAVIS D'IMPÔT 2017\nIMPÔT SUR LES REVENUS\nd Fannée 2016\n\n \n\nPour vos _ démarches,\npas besoin doiginal —\nMc d furir un —\nphotocopie, vérifiable sur —\nTmpots gouv vn\n\nVotre situation\n\n \n\nVos rétérences.\n\nPour accéder à votre espace partculior MONTANT À PAYER\nNuméro fiscal | | A us ario 15/00/2017 (41)\n\nN* daccès en ligne voirvouo déciaration | | Détail du montant à payer\nRevenu fiscal d référence Montart de vtr impôt su e revors\n# | Rétéronce de 'avis <VRRRRS | Versemens sur 1er acompte\nVersomontssur 26 acompto\n\nNuméro F —\n\nNuméro de rôle 016 A\nDate c'étaissement 2m0762017|\nDate de mise en recouvrement 3vo7æ2017|\n\n \n\n \n\n \n\n3899,00 €\n3893006\n\n \n\n \n\nLa somme que vous davez payer est supérieure à 2 000 €\nLa loirend obligatoie le paiement de cette somme par un des moyens suivants, à votre choix :\n\nur impots.gouv.fr: payez en igne ou adhérez au prélèvement à léchéance en vous connectant à vore\nspaco pariclor, pislissoz-vous guider\n\npartéléphone, courrir où couriel pour adhérer au prélèvement à échéanco (aux coordonnéesindiquées\ndansle cadre - Vos démarches »\n\nPour 2018,vous pourrez achérerau prélèvement mensue\n\x0c"""
I need your help to solve this problem, I want to refresh a QlistWidget in pyqt4 when I add a new register from another QMainWindow not in the principal, i tried with "repaint()" but it doesn´t work, to understand it better I post the code
This is the main window where I added all items from a DB
class Psicologo(QMainWindow):
def __init__(self, parent=None):
super(Psicologo, self).__init__(parent)
uic.loadUi('inicio.ui', self)
self.button_volver.clicked.connect(self.regresar)
self.button_nvo_psicologo.clicked.connect(self.nuevoPsicologo)
query = "SELECT * FROM user"
cursor, conexion = CreateConexion()
cursor.execute(query)
registro = cursor.fetchall()
for i in registro:
self.lista_psicologos.addItem(i[1]+" "+i[2]+" "+i[3])
def regresar(self):
self.parent().show()
self.close()
def nuevoPsicologo(self):
self.hide()
nuevo_form = AltaPsico(self)
nuevo_form.show()
And here is the other window where I create a new register
class AltaPsico(QMainWindow):
def __init__(self, parent=None):
super(AltaPsico, self).__init__(parent)
uic.loadUi('alta_paciente.ui', self)
self.combo_sexo.hide()
self.label_12.hide()
self.text_comentario.hide()
self.label_14.hide()
self.line_correo_2.hide()
self.label_13.hide()
self.button_volver.clicked.connect(self.regresar)
self.button_guardar.clicked.connect(self.guardar)
self.button_eliminar.hide()
def guardar(self):
nombre = self.line_nombre.text()
app = self.line_app.text()
apm = self.line_apm.text()
domicilio = self.line_domicilio.text()
edad = self.line_edad.text()
telefono = self.line_telefono.text()
especialidad = self.line_especialidad.text()
correo = self.line_correo.text()
usuario = self.line_usuario.text()
password = self.line_password.text()
pass2 = self.line_password_2.text()
if password == pass2:
if edad.isdigit():
if validate_email(correo):
if telefono.isdigit():
query = "INSERT INTO user(idUser, Nombre, ApPaterno, ApMaterno, Domicilio, Edad, Telefono, Especialidad, Correo, Usuario, Password, Tipo) VALUES (0,'"+nombre+"','"+app+"', '"+apm+"', '"+domicilio+"', '"+edad+"', '"+telefono+"', '"+especialidad+"', '"+correo+"', '"+usuario+"', '"+password+"', 2);"
print (query)
cursor, conexion = CreateConexion()
cursor.execute(query)
msgBoxCancel = QtGui.QMessageBox( self )
msgBoxCancel.setIcon( QtGui.QMessageBox.Information )
msgBoxCancel.setText( "Usuario registrado con exito" )
msgBoxCancel.addButton( QtGui.QMessageBox.Ok )
msgBoxCancel.exec_()
conexion.commit()
conexion.close()
self.parent().show()
self.QMainWindow.update()
self.close()
else:
msgBoxCancel = QtGui.QMessageBox( self )
msgBoxCancel.setIcon( QtGui.QMessageBox.Information )
msgBoxCancel.setText( "¡Telefono invalido, ingrese telefono valido!" )
msgBoxCancel.addButton( QtGui.QMessageBox.Ok )
msgBoxCancel.exec_()
else:
msgBoxCancel = QtGui.QMessageBox( self )
msgBoxCancel.setIcon( QtGui.QMessageBox.Information )
msgBoxCancel.setText( "¡Correo invalido, ingrese correo valido!" )
msgBoxCancel.addButton( QtGui.QMessageBox.Ok )
msgBoxCancel.exec_()
else:
msgBoxCancel = QtGui.QMessageBox( self )
msgBoxCancel.setIcon( QtGui.QMessageBox.Information )
msgBoxCancel.setText( "¡Ingrese una edad valida!" )
msgBoxCancel.addButton( QtGui.QMessageBox.Ok )
msgBoxCancel.exec_()
else:
msgBoxCancel = QtGui.QMessageBox( self )
msgBoxCancel.setIcon( QtGui.QMessageBox.Information )
msgBoxCancel.setText( "¡La contraseña no coincide, intentelo de nuevo!" )
msgBoxCancel.addButton( QtGui.QMessageBox.Ok )
msgBoxCancel.exec_()
def regresar(self):
self.parent().repaint()
self.parent().show()
self.close()
When the register ends succesfully this window closes automatically but when the principal shows again the listWidget shows the same registers at the begin.
I hope this community can help me, i´ve been searching about this topic but i can´t find anything.
If the database is modified, the GUI is not notified so the data must be requested again:
class Psicologo(QMainWindow):
def __init__(self, parent=None):
super(Psicologo, self).__init__(parent)
uic.loadUi('inicio.ui', self)
self.button_volver.clicked.connect(self.regresar)
self.button_nvo_psicologo.clicked.connect(self.nuevoPsicologo)
self.load_from_db()
def load_from_db(self):
self.lista_psicologos.clear()
query = "SELECT * FROM user"
cursor, conexion = CreateConexion()
cursor.execute(query)
registro = cursor.fetchall()
for i in registro:
self.lista_psicologos.addItem("{} {} {}".format(i[1], i[2], i[3]))
def regresar(self):
self.parent().show()
self.close()
def nuevoPsicologo(self):
self.hide()
nuevo_form = AltaPsico(self)
nuevo_form.show()
def guardar(self):
# ...
conexion.commit()
conexion.close()
self.parent().show()
self.parent().load_from_db()
I'm having a problem trying to do a very simple user interface. I made my UI with Qt Designer, and then with pyuic4 I got my python code. Then I programmed the function I needed, and compiled with Eclipse IDE.
The code I got from pyuic4 is:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'Dni.ui'
#
# Created: Sat Apr 14 02:44:34 2012
# by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(371, 217)
Dialog.setMinimumSize(QtCore.QSize(371, 217))
self.layoutWidget = QtGui.QWidget(Dialog)
self.layoutWidget.setGeometry(QtCore.QRect(30, 30, 311, 151))
self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
self.gridLayout = QtGui.QGridLayout(self.layoutWidget)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.label = QtGui.QLabel(self.layoutWidget)
self.label.setObjectName(_fromUtf8("label"))
self.horizontalLayout.addWidget(self.label)
self.entrada = QtGui.QLineEdit(self.layoutWidget)
self.entrada.setObjectName(_fromUtf8("entrada"))
self.horizontalLayout.addWidget(self.entrada)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.boton = QtGui.QPushButton(self.layoutWidget)
self.boton.setObjectName(_fromUtf8("boton"))
self.gridLayout.addWidget(self.boton, 1, 0, 1, 1)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.label_3 = QtGui.QLabel(self.layoutWidget)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.horizontalLayout_2.addWidget(self.label_3)
self.salida = QtGui.QLineEdit(self.layoutWidget)
self.salida.setObjectName(_fromUtf8("salida"))
self.horizontalLayout_2.addWidget(self.salida)
self.gridLayout.addLayout(self.horizontalLayout_2, 2, 0, 1, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Dialog", "Introduzca su DNI", None, QtGui.QApplication.UnicodeUTF8))
self.boton.setText(QtGui.QApplication.translate("Dialog", "Hallar NIF", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("Dialog", "NIF:", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
And the code I made with the function I need:
from Dni import Ui_Dialog
from PyQt4 import QtCore, QtGui
LETRADNI = {0:'T', 1:'R', 2:'W', 3:'A', 4:'G', 5:'M', 6:'Y', 7:'F', 8:'P', 9:'D', 10:'X', 11:'B', 12:'N',
13: 'J', 14:'Z', 15:'S', 16:'Q', 17:'V', 18:'H', 19:'L', 20:'C', 21:'K', 22:'E'}
# Se hereda de la clase QtGui.QMainWindow
class Principal(QtGui.QMainWindow):
# Se define el constructor de la clase __init__
def __init__(self):
# Se llama al constructor de la clase padre
QtGui.QMainWindow.__init__(self)
# Se crea la instancia de Ui_Dialog
self.ventana = Ui_Dialog()
self.ventana.setupUi(self)
# Se conectan las señales con los slots
self.connect(self.ventana.boton,QtCore.SIGNAL('clicked()'), self.letradni)
def Calcula_letra_dni(dni):
'''Función Calcula_letra_dni:
Funcionamiento:
La función recibe el valor entero dni. Posteriormente calculará el resto de la división
por 23. Éste número se buscará en el diccionario 'LETRADNI' para obtener la letra correspondiente
a ese DNI.
Argumentos
dni -- número del documento nacional de identidad (int)
Devuelve:
Una cadena (string) -- DNI + letra preparado para salida por pantalla
'''
#if len(str(dni))>8 & len(str(dni))<7:
# raise ValueError('El dni debe tener entre 7 y 8 cifras')
num_letra = dni % 23.0
letra = LETRADNI[num_letra]
return '{0}-{1}'.format(dni,letra)
def letradni(self):
self.ventana.salida.setText(Calcula_letra_dni(self.ventana.entrada.text()))
The first one compiles and runs, it shows my ui perfectly.
Compiling the second one I get an error that says:
Description Resource Path Location Type
Undefined variable from import: QString Dni.py /Dni line 18 PyDev Problem
Can anyone help me?
Thanks in advance.
First off, I think your actual listed problem is related to Eclipse, pydev, and your projects PYTHONPATH. Review this to make sure you have properly set up everything and included PyQt4 in your pythonpath:
http://popdevelop.com/2010/04/setting-up-ide-and-creating-a-cross-platform-qt-python-gui-application/
After that, you seem to have some problems with your code beyond what you have mentioned...
First you define Principal class, then a Calcula_letra_dni function, but then you are defining what looks like a class instance method letradni which should be part of Principal:
class Principal(QtGui.QMainWindow):
# Se define el constructor de la clase __init__
def __init__(self):
...
def letradni(self):
...
def Calcula_letra_dni(dni):
...
Then it looks like you will raise an exception when you try to do math on a string (thanks #Avaris) and float:
num_letra = dni % 23.0
You should probably convert that string to a float first: num_letra = float(dni) % 23.0
And finally, I think you also forgot to define a main for your application. You have the one that is autogenerated in your Dni.py, but you didn't write one for your actual entry point script:
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
form = Principal()
form.show()
sys.exit(app.exec_())