I am doing a image viewer pyqt gui application with sqlite3 database. But I am not able to upload images to the database. how can I do this?
def open(ui):
fname = QFileDialog.getOpenFileName(ui, 'Open file','c:\\',"Image files (*.jpg *.gif)")
ui.FirmEditLogoEntry.setText(fname)
I am able to get file name. But can’t convert to binary.
Please Help me to do this.
Thanks
With the QFileDialog you only get the name of the file, you must use that information to read the bytes of the file for it use QFile and save that data in BLOBs. In the next part I show an example:
import sys
from PyQt4.QtGui import *
from PyQt4.QtSql import *
from PyQt4.QtCore import *
def createConnection():
db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName(':memory:')
if not db.open():
QMessageBox.critical(None, "Cannot open database",
"Unable to establish a database connection.\n"
"This example needs SQLite support. Please read the Qt SQL "
"driver documentation for information how to build it.\n\n"
"Click Cancel to exit.",
QMessageBox.Cancel)
return False
query = QSqlQuery()
return query.exec_('''CREATE TABLE IF NOT EXISTS imgTable
(id INTEGER primary key AUTOINCREMENT, filename TEXT, imagedata BLOB)''')
class Widget(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
vbox = QVBoxLayout(self)
self.load_btn = QPushButton("Select Image")
self.combo = QComboBox()
self.label = QLabel()
self.model = QSqlTableModel()
self.model.setTable("imgTable")
self.model.select()
self.combo.setModel(self.model)
self.combo.setModelColumn(1)
vbox.addWidget(self.load_btn)
vbox.addWidget(self.combo)
vbox.addWidget(self.label)
self.load_btn.clicked.connect(self.load_image)
self.combo.currentIndexChanged.connect(self.on_change_select)
def on_change_select(self, row):
ix = self.combo.model().index(row, 2)
pix = QPixmap()
pix.loadFromData(ix.data())
self.label.setPixmap(pix)
def load_image(self):
fname = QFileDialog.getOpenFileName(self, 'Open file', QDir.currentPath(), "Image files (*.jpg, *.gif, *.png)")
if fname:
self.saveImage(fname)
def saveImage(self, filename):
file = QFile(filename)
if not file.open(QIODevice.ReadOnly):
return
ba = file.readAll()
name = QFileInfo(filename).fileName()
record = self.model.record()
record.setValue("filename", name)
record.setValue("imagedata", ba)
if self.model.insertRecord(-1, record):
self.model.select()
if __name__ == '__main__':
app = QApplication(sys.argv)
if not createConnection():
sys.exit(-1)
w = Widget()
w.show()
sys.exit(app.exec_())
Related
i want to display in a QlistView the index and the file name, so i subclassed QSqlQueryModel to override the data() method but i'm always getting None, it seems like i'm displaying the data befor adding it or some thing like that here is the concerned part of my code :
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
import sys, os
import pathlib
CURRENT_PATH = pathlib.Path(__file__).parent
connection = QSqlDatabase.addDatabase("QSQLITE")
connection.setDatabaseName("medias.sqlite")
connection.open()
print(connection.open())
createTableQuery = QSqlQuery()
createTableQuery.exec(
"""
CREATE TABLE fichiers (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
path VARCHAR(300) NOT NULL
)
"""
)
print(connection.tables())
class PlaylistModel(QSqlQueryModel):
def __init__(self, playlist,*args, **kwargs):
super(PlaylistModel, self).__init__(*args, **kwargs)
self.playlist = playlist or [[]]
def data(self, index, role):
row = index.row()
if role == Qt.DisplayRole:
try:
text = self.playlist[index.row()][1]
except IndexError:
text = None
return text # always getting None
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.play_list = []
self.setGeometry(900,180,800,600)
self.setWindowTitle("Media Display")
self.model = PlaylistModel(self.play_list)
self.model.setQuery("SELECT path FROM fichiers")
self.listview = QListView()
self.listview.setModel(self.model)
self.listview.setModelColumn(1)
self.main_layout()
self.DbConnect()
def DbConnect(self):
self.connection = QSqlDatabase.addDatabase("QSQLITE")
self.connection.setDatabaseName("medias.sqlite")
self.connection.open()
createTableQuery = QSqlQuery()
createTableQuery.exec(
""" CREATE TABLE fichiers (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
path VARCHAR(300) NOT NULL
)
"""
)
self.model.setQuery("SELECT path FROM fichiers")
return True
def addToPlaylist(self):
self.play_list.clear()
model = self.listview.model()
for row in range(model.rowCount()):
index = model.index(row , 0)
item = model.data(index, Qt.DisplayRole)
self.play_list.append(item)
print('the playlist',self.play_list)
def addImage(self):
fichier_base, _ = QFileDialog.getOpenFileName(self, 'select video', QDir.homePath(),"Images (*.png *.xpm *.jpg *.jpeg)")
if fichier_base:
query = QSqlQuery()
query.prepare("""INSERT INTO fichiers (path) VALUES (?)""")
query.addBindValue(fichier_base)
if query.exec_():
last_query = self.model.query().executedQuery()
self.model.setQuery("")
self.model.setQuery(last_query)
else:
print(query.lastError().text())
def clearDb(self):
query = QSqlQuery(self.connection)
if self.connection.open():
query.exec("DELETE FROM fichiers")
query.clear()
last_query = self.model.query().executedQuery()
self.model.setQuery("")
self.model.setQuery(last_query)
def main_layout(self):
self.add_img_btn = QPushButton("Add image ")
self.add_img_btn.setFixedWidth(150)
self.add_img_btn.clicked.connect(self.addImage)
self.clear_db_btn = QPushButton("clear DB")
self.clear_db_btn.setFixedWidth(150)
self.clear_db_btn.clicked.connect(self.clearDb)
self.refresh_btn = QPushButton("refresh")
self.refresh_btn.setFixedWidth(150)
self.refresh_btn.clicked.connect(self.addToPlaylist)
group_btns = QHBoxLayout()
main_app = QVBoxLayout()
main_app.addWidget(self.listview)
main_app.addLayout(group_btns)
group_btns.addWidget(self.add_img_btn)
group_btns.addWidget(self.clear_db_btn)
group_btns.addWidget(self.refresh_btn)
vboxlay = QHBoxLayout()
vboxlay.addLayout(main_app)
widget = QWidget(self)
self.setCentralWidget(widget)
widget.setLayout(vboxlay)
if __name__ == '__main__':
app= QApplication(sys.argv)
window = MainWindow()
window.setStyleSheet('background-color:#fff;')
window.show()
sys.exit(app.exec_())
on a previous app i subclassed the QAbstractListModel Class and i did it like that
class PlaylistModel(QAbstractListModel):
def __init__(self, playlist, *args, **kwargs):
super(PlaylistModel, self).__init__(*args, **kwargs)
self.playlist = playlist
def data(self, index, role):
if role == Qt.DisplayRole:
media = self.playlist.media(index.row())
print('mediaaaaaaa', media )
print('plaaaaaylist', self.playlist )
name_video = media.canonicalUrl().fileName()
i = index.row() + 1
return f"{i} - {name_video}"
def rowCount(self, index):
return self.playlist.mediaCount()
The following should be taken into account:
If you are going to show information from a table then you must use a QSqlTableModel. QSqlQueryModel is a read-only model whose objective is to show very particular query information. On the other hand, QSqlTableModel has several methods to handle the tables.
If you are going to modify how the information of the model is shown in a view then you must use a delegate. This makes the modifications more flexible since you can have different models applying the same modifications to the views.
Considering the above, the solution is:
import sys
from PyQt5.QtCore import QDir
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
from PyQt5.QtWidgets import (
QApplication,
QFileDialog,
QHBoxLayout,
QListView,
QMainWindow,
QPushButton,
QStyledItemDelegate,
QVBoxLayout,
QWidget,
)
def create_connection():
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("medias.sqlite")
if not db.open():
print(db.lastError().text())
return False
q = QSqlQuery()
if not q.exec(
"""
CREATE TABLE IF NOT EXISTS fichiers (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
path VARCHAR(300) NOT NULL
)
"""
):
print(q.lastError().text())
return False
print(db.tables())
return True
class StyledItemDelegate(QStyledItemDelegate):
def initStyleOption(self, option, index):
super().initStyleOption(option, index)
option.text = f"{index.row() + 1} - {index.data()}"
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.play_list = []
self.setGeometry(900, 180, 800, 600)
self.setWindowTitle("Media Display")
self.model = QSqlTableModel()
self.model.setTable("fichiers")
self.model.select()
self.listview = QListView()
delegate = StyledItemDelegate(self.listview)
self.listview.setItemDelegate(delegate)
self.listview.setModel(self.model)
self.listview.setModelColumn(1)
self.init_ui()
def addImage(self):
fichier_base, _ = QFileDialog.getOpenFileName(
self, "select video", QDir.homePath(), "Images (*.png *.xpm *.jpg *.jpeg)"
)
if fichier_base:
rec = self.model.record()
rec.setValue("path", fichier_base)
self.model.insertRecord(-1, rec)
self.model.select()
def clearDb(self):
query = QSqlQuery()
query.exec("DELETE FROM fichiers")
self.model.select()
def init_ui(self):
self.add_img_btn = QPushButton("Add image ")
self.add_img_btn.setFixedWidth(150)
self.add_img_btn.clicked.connect(self.addImage)
self.clear_db_btn = QPushButton("clear DB")
self.clear_db_btn.setFixedWidth(150)
self.clear_db_btn.clicked.connect(self.clearDb)
self.refresh_btn = QPushButton("refresh")
self.refresh_btn.setFixedWidth(150)
group_btns = QHBoxLayout()
main_app = QVBoxLayout()
main_app.addWidget(self.listview)
main_app.addLayout(group_btns)
group_btns.addWidget(self.add_img_btn)
group_btns.addWidget(self.clear_db_btn)
group_btns.addWidget(self.refresh_btn)
widget = QWidget()
vboxlay = QHBoxLayout(widget)
vboxlay.addLayout(main_app)
self.setCentralWidget(widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
if not create_connection():
sys.exit(-1)
window = MainWindow()
window.setStyleSheet("background-color:#fff;")
window.show()
sys.exit(app.exec_())
I am writing a program using python 3.4 to allow a user to enter their Name and Surname and once they hit save the data should save in the db an display on screen. The Data saves to the db fine( I know this because every time I close the program and run it the previous entry displays). My problem here is that when I enter the data and hit save, it does not automatically display on the screen in the tabelView widget. I used QT designer 4 to create the widget and my database table only contains two columns, Full_Name and Surname. How can I get my entry to display immediately after hitting the save button?
Here's my code:
import sys
from Nametest import *
from PyQt4 import QtSql, QtGui
import mysql.connector
conn=mysql.connector.connect(host="localhost", user="root", passwd="shotokan", db="name")
cursor=conn.cursor()
def createConnection():
db = QtSql.QSqlDatabase.addDatabase('QMYSQL')
db.setHostName('localhost')
db.setDatabaseName('name')
db.setUserName('root')
db.setPassword('shotokan')
db.open()
print (db.lastError().text())
return True
class MyForm(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.model = QtSql.QSqlTableModel(self)
self.model.setTable("fullname")
self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.model.select()
self.ui.tableView.setModel(self.model)
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()' ),self.InsertRecords)
def InsertRecords(self):
cursor.execute( """INSERT INTO fullname (First_Name, Surname)VALUES('%s','%s')""" %(self.ui.lineEdit.text(),self.ui.lineEdit_2.text()))
conn.commit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
if not createConnection():
sys.exit(1)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
Here is an image of my Widget:
Don't use 2 technologies to do the same task, if you have used QSqlTableModel to display the information then use that model to do the insert:
class MyForm(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.model = QtSql.QSqlTableModel(self)
self.model.setTable("fullname")
self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.model.select()
self.ui.tableView.setModel(self.model)
self.ui.pushButton.clicked.connect(self.InsertRecords)
def InsertRecords(self):
db = self.model.database()
db.transaction()
record = self.model.record()
record.setValue("First_Name", self.ui.lineEdit.text())
record.setValue("Surname", self.ui.lineEdit_2.text())
if self.model.insertRecord(-1, record):
print("successful insertion")
self.model.submitAll()
else:
db.rollback()
Note: Do not use concatenation to create a query since your application is susceptible to SQL Injection.
I have main class with sub-classes as tabs.
I have GUI like this:
QApp.py - Mainwindow
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5 import QtGui, QtWidgets
from QFilesTab import Files
from QWebservicesTab import Webservices
import qdarkstyle
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.task_bar()
self.tab_layout()
self.graph_elements()
self.center()
def task_bar(self):
### actions on meenubar
exitAct = QtWidgets.QAction('&Exit', self, shortcut='Ctrl+Q', statusTip='Exit application')
exitAct.triggered.connect(self.close)
moreinfo = QtWidgets.QAction('&Help', self, statusTip='More information')
moreinfo.triggered.connect(self.information)
### menubar
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAct)
fileMenu = menubar.addMenu('&Help')
fileMenu.addAction(moreinfo)
def graph_elements(self):
### basic geometry and color
self.setWindowTitle('Villain')
self.setWindowIcon(QtGui.QIcon('dc1.png'))
self.setStyleSheet((qdarkstyle.load_stylesheet_pyqt5()))
def tab_layout(self):
self.tabwidget = QtWidgets.QTabWidget()
self.tabwidget.addTab(Files(), 'Files Import') ### ADDED SUB_CLASS AS QTABWIDGET
self.tabwidget.addTab(Webservices(), 'Webservice')
self.setCentralWidget(self.tabwidget)
### center main window
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def information(self):
QtWidgets.QMessageBox.information(self,'Information','Version: 2.0\n'\
'Please, contact karol.chojnowski#digitalcaregroup.com for comments and suggestions\n\n'\
'Digital Care - Data Processing Team')
This is my subclass, which i have as 'Files Import' tab on screen. I have to use credentials to connect with sql. So i ll try get it from my __main__
QFilesTab.py - subclass as qtabwidget
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import threading
from PyQt5 import QtGui, QtWidgets, QtCore
import pyodbc
class Files(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.layout_init()
def layout_init(self):
operator = ['TMobile', 'PLK', 'Play', 'Orange']
variant = ['Select variant', 'Numer usługi/polisy', 'IMEI', 'PESEL', 'NIP',
'REGON', 'Nazwisko', 'Nazwa firmy']
###partners
self.pvbox = QtWidgets.QVBoxLayout()
self.buttongroup = QtWidgets.QButtonGroup(self)
for elements, forms in enumerate(operator):
element = str(forms)
self.partners = QtWidgets.QRadioButton(element)
self.buttongroup.addButton(self.partners, )
self.pvbox.addWidget(self.partners,)
self.buttongroup.buttonClicked.connect(self.on_itemSelected)
self.buttongroup.buttonClicked['int'].connect(self.on_itemSelected)
###variants
self.variants = QtWidgets.QComboBox()
for elements, forms in enumerate(variant):
element = str(forms)
self.variants.addItem(element)
self.variants.model().item(0).setEnabled(False)
self.variants.activated.connect(self.update_textbox)
self.textbox = QtWidgets.QLineEdit()
self.tablewidget = QtWidgets.QTableWidget()
self.tablewidget.setColumnCount(5)
self.tablewidget.setHorizontalHeaderLabels(['FileNameOriginal', 'OrderItemCode', 'Imported','InfoCode', 'Row'])
self.tablewidget.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.tablewidget.horizontalHeader().setStretchLastSection(True)
self.tablewidget.resizeColumnsToContents()
self.tablewidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.tablewidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.pb = QtWidgets.QPushButton(self.tr('Run process'))
self.pb.setDisabled(True)
self.textbox.textChanged.connect(self.disableButton)
self.pb.clicked.connect(self.on_clicked_pb)
self.clearbutton = QtWidgets.QPushButton(self.tr('Clear all'))
self.clearbutton.setDisabled(True)
self.clearbutton.clicked.connect(self.on_clicked_clear)
vgroupbox = QtWidgets.QGroupBox('Options')
pgroupbox = QtWidgets.QGroupBox('Partner')
mainpanel = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.LeftToRight)
variantpanel = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom)
variantpanel.addWidget(self.variants)
variantpanel.addWidget(self.textbox)
variantpanel.addWidget(self.pb)
variantpanel.addWidget(self.clearbutton)
mainpanel.addWidget(pgroupbox)
mainpanel.addWidget(vgroupbox)
vgroupbox.setLayout(variantpanel)
test = QtWidgets.QVBoxLayout(self)
test.addLayout(self.pvbox)
pgroupbox.setLayout(test)
grid = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom, self)
grid.addLayout(mainpanel)
grid.addWidget(self.tablewidget)
self.setLayout(grid)
def setCredentials(self, credentials): ################################
self._credentials = credentials
def update_textbox(self, text):
self.textbox.clear()
textline = self.variants.itemText(text)
self.textbox.setPlaceholderText(textline)
if textline == 'IMEI':
regexp = QtCore.QRegExp('^(?=.{0,16}$)(0\d+|[1-9][0-9]+)$')
elif textline == 'PESEL':
regexp = QtCore.QRegExp('^(?=.{0,11}$)(0\d+|[1-9][0-9]+)$')
elif textline == 'NIP':
regexp = QtCore.QRegExp('^(?=.{0,10}$)(0\d+|[1-9][0-9]+)$')
elif textline == 'REGON':
regexp = QtCore.QRegExp('^(?=.{0,9}$)(0\d+|[1-9][0-9]+)$')
elif textline == 'Nazwisko':
regexp = QtCore.QRegExp('[A-Za-zżźćńółęąśŻŹĆĄŚĘŁÓŃ]*')
else:
regexp = None
self.textbox.setValidator(QtGui.QRegExpValidator(regexp))
#QtCore.pyqtSlot(QtWidgets.QAbstractButton)
#QtCore.pyqtSlot(int)
def on_itemSelected(self, index):
if isinstance(index, QtWidgets.QAbstractButton):
self.base = None
element = '{}'.format(index.text())
if element == 'Play':
self.base = 'W2_FileImportWorkerP4'
elif element == 'TMobile':
self.base= 'W2_FileImportWorkerTmobileFIX'
elif element == 'Orange':
self.base = 'W2_FileImportWorkerOCP'
elif element == 'PLK':
self.base = 'W2_FileImportWorkerPLK'
return self.base
elif isinstance(index, int):
pass
#QtCore.pyqtSlot()
def disableButton(self):
val = bool(self.textbox.text())
self.pb.setDisabled(not val)
self.clearbutton.setDisabled(not val)
#QtCore.pyqtSlot()
def disablesql(self):
self.textbox.setDisabled(True)
self.pb.setDisabled(True)
self.clearbutton.setDisabled(True)
#QtCore.pyqtSlot()
def enablesql(self):
self.textbox.setDisabled(False)
self.pb.setDisabled(False)
self.clearbutton.setDisabled(False)
### run process button
#QtCore.pyqtSlot()
def on_clicked_pb(self):
if self.textbox.text():
threading.Thread(target=self.sql_query, daemon=True).start()
### clear all
#QtCore.pyqtSlot()
def on_clicked_clear(self):
if self.textbox.text():
self.textbox.clear()
self.tablewidget.setRowCount(0)
self.tablewidget.setColumnWidth(3, 200)
def table_performance(self):
self.tablewidget.resizeColumnsToContents()
self.tablewidget.setColumnWidth(4, 2500)
self.tablewidget.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
#QtCore.pyqtSlot(str, str)
def show_warning(self, title, msg):
QtWidgets.QMessageBox.information(self, title, msg)
#QtCore.pyqtSlot(str, str)
def show_ok(self, title, msg):
QtWidgets.QMessageBox.information(self, title ,msg)
#QtCore.pyqtSlot()
def clear_items(self):
self.tablewidget.setRowCount(0)
#QtCore.pyqtSlot(int, int, str)
def add_item(self, row, column, val):
if row >= self.tablewidget.rowCount():
self.tablewidget.insertRow(self.tablewidget.rowCount())
newitem = QtWidgets.QTableWidgetItem(val)
self.tablewidget.setItem(row, column, newitem)
#QtCore.pyqtSlot()
def sort_items(self):
self.tablewidget.sortItems(0, order=QtCore.Qt.DescendingOrder)
def sql_query(self):
ser = '10.96.5.17\dqinstance'
print(self.credentials) #check
username, pwd = self._credentials ############################
imei = '%' + self.textbox.text() + '%'
self.clear_items()
try:
self.disablesql()
connection = pyodbc.connect(driver='{SQL Server}', server=ser,
user=username, password=pwd)
if self.base == 'W2_FileImportWorkerTmobileFIX':
cursor = connection.cursor()
res = cursor.execute('''
SELECT FI.FileNameOriginal,
FI.OrderItemCode,
FIR.Imported,
FIRI.InfoCode,
FR.Row
FROM BIDQ_W2_DB.dbo.[FileImports] AS FI
JOIN BIDQ_W2_DB.dbo.[FileImportRows] AS FIR ON FI.Id = FIR.FileImportId
JOIN BIDQ_W2_DB.dbo.[FileRows] AS FR ON FIR.RowId = FR.RowId
LEFT JOIN BIDQ_W2_DB.dbo.FileImportRowInfoes AS FIRI ON FR.RowId = FIRI.RowId
WHERE (FI.WorkerCode = ? or FI.WorkerCode = ?) and FR.Row LIKE ? ''',
(self.base, self.base, imei))
elif self.base == 'All':
cursor = connection.cursor()
res = cursor.execute(''' SELECT FI.FileNameOriginal,
FI.OrderItemCode,
FIR.Imported,
FIRI.InfoCode,
FR.Row
FROM BIDQ_W2_DB.dbo.[FileImports] AS FI
JOIN BIDQ_W2_DB.dbo.[FileImportRows] AS FIR ON FI.Id = FIR.FileImportId
JOIN BIDQ_W2_DB.dbo.[FileRows] AS FR ON FIR.RowId = FR.RowId
LEFT JOIN BIDQ_W2_DB.dbo.FileImportRowInfoes AS FIRI ON FR.RowId = FIRI.RowId
WHERE FR.Row LIKE ? ''',(imei))
else:
cursor = connection.cursor()
res = cursor.execute('''
SELECT FI.FileNameOriginal,
FI.OrderItemCode,
FIR.Imported,
FIRI.InfoCode,
FR.Row
FROM BIDQ_W2_DB.dbo.[FileImports] AS FI
JOIN BIDQ_W2_DB.dbo.[FileImportRows] AS FIR ON FI.Id = FIR.FileImportId
JOIN BIDQ_W2_DB.dbo.[FileRows] AS FR ON FIR.RowId = FR.RowId
LEFT JOIN BIDQ_W2_DB.dbo.FileImportRowInfoes AS FIRI ON FR.RowId = FIRI.RowId
WHERE FI.WorkerCode = ? and FR.Row LIKE ? ''', (self.base, imei))
if not cursor.rowcount:
QtCore.QMetaObject.invokeMethod(self, 'show_warning',
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, 'IMEI'), QtCore.Q_ARG(str, 'No items found'))
else:
QtCore.QMetaObject.invokeMethod(self, 'clear_items', QtCore.Qt.QueuedConnection)
QtCore.QThread.msleep(10)
for row, form in enumerate(res):
for column, item in enumerate(form):
QtCore.QMetaObject.invokeMethod(self, 'add_item',
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(int, row), QtCore.Q_ARG(int, column),
QtCore.Q_ARG(str, str(item)))
QtCore.QThread.msleep(10)
QtCore.QMetaObject.invokeMethod(self, 'sort_items', QtCore.Qt.QueuedConnection)
self.table_performance()
QtCore.QMetaObject.invokeMethod(self, 'show_ok',
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, 'Done'), QtCore.Q_ARG(str, 'Items found'))
cursor.close()
except:
QtCore.QMetaObject.invokeMethod(self, 'show_warning',
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, 'Error'), QtCore.Q_ARG(str, 'Something went wrong\n\n' \
'Contact karol.chojnowski#digitalcaregroup.com'))
self.enablesql()
When i try get credentials from main - got error like this :
Im trying to pass credentials in __main__ to Files(). What is wrong? Before when I had only one main class without tabs it worked.... What is the best way to pass credentials in this case? Im asking because im goin to use these credentials in other tabs. Should I create subclass only for credentials?
# -- coding: utf-8 --
import sys
from PyQt5 import QtWidgets,QtGui
from QLogin import LoginDialog
from QApp import MainWindow
from QFilesTab import Files
import os
def resource_path(relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath('.'), relative_path)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
login = LoginDialog()
login.setWindowIcon(QtGui.QIcon(resource_path('dc1.png')))
if login.exec_() != QtWidgets.QDialog.Accepted:
sys.exit(-1)
files = Files()
window = MainWindow()
window.setWindowIcon(QtGui.QIcon(resource_path('dc1.png')))
window.setGeometry(500, 150, 800, 500)
files.setCredentials(login.credentials()) ###############################
window.show()
sys.exit(app.exec_())
In code i put multiple ################# when i have problematic places.
Edited:
LoginDialog
# -- coding: utf-8 --
from PyQt5.QtWidgets import QLineEdit,QDialogButtonBox,QFormLayout,QDialog,QMessageBox
from PyQt5 import QtWidgets,QtCore
import qdarkstyle
import pyodbc
class LoginDialog(QDialog):
def __init__(self, parent=None):
super(LoginDialog,self).__init__(parent)
self.init_ui()
def init_ui(self):
### delete question mark
self.setWindowFlags(self.windowFlags()
^ QtCore.Qt.WindowContextHelpButtonHint)
### login & password fields
self.username = QLineEdit(self)
self.password = QLineEdit(self)
self.password.setEchoMode(QLineEdit.Password)
loginLayout = QFormLayout()
loginLayout.addRow('Username', self.username)
loginLayout.addRow('Password', self.password)
self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttons.accepted.connect(self.control)
self.buttons.rejected.connect(self.reject)
layout = QtWidgets.QVBoxLayout(self)
layout.addLayout(loginLayout)
layout.addWidget(self.buttons)
self.setLayout(layout)
### set window title & stylesheet
self.setWindowTitle('Villain - 10.96.6.14 ')
#self.setWindowIcon(QtGui.QIcon('dc1.png'))
self.setStyleSheet((qdarkstyle.load_stylesheet_pyqt5()))
###lock resize
self.setSizeGripEnabled(False)
self.setFixedSize(self.sizeHint())
def credentials(self):
return self.username.text(), self.password.text()
###log by usins sql credentials
def control(self):
ser = '10.96.5.17\dqinstance'
login = self.username.text()
pwd = self.password.text()
try:
self.connection = pyodbc.connect(driver='{SQL Server}', server=ser,
user=login, password=pwd)
cursor = self.connection.cursor()
cursor.close()
self.accept()
except:
QMessageBox.warning(self, 'Error', 'Wrong username or password! \n\n'
'Please use the SQL Server credentials ')
This is how I solved this:
In Main.py i have passed argument from LoginDIalog class to MainWindow class.
window.tab_layout(login.credentials())
In QApp.py i have edited method tab_layout:
def tab_layout(self, credentials):
self.tabwidget = QtWidgets.QTabWidget()
self.tabwidget.addTab(Files(credentials), 'Files Import')
self.tabwidget.addTab(Webservices(), 'Webservice')
self.setCentralWidget(self.tabwidget)
In QFilesTab.py i have added to Files class constuctor self._credentials = credentials and deleted method setCredentials. Now, my sql_query method is using credentials from constuctor.
I'm currently working on a GUI with PyQt5.
I am using the menu bar to load a file, when i click it the program calls this function:
def getxlsbase(self):
filePath_base, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Select file', './', 'Excel Files (*.xls *.xlsx)')
base = xlrd.open_workbook(filePath_base)
hoja_base = base.sheet_by_index(0)
num_row = hoja_base.nrows
num_col = hoja_base.ncols
When the browse window opens and I select the file, a blank Excel document opens, how can I avoid this?
EDIT:
I tried this method but I still have this issue, it only happens with excel docs. I am using Spyder3
from tkinter import *
from tkinter import filedialog
root = Tk()
root.withdraw()
filepath = filedialog.askopenfilename()
print(filepath)
I don't know if I understood the question correctly, but if, like me, when you open an excel document, a window opens with a file selection, then you can do this:
def get_path_excel_file(self):
excel_path, _ = QFileDialog.getOpenFileName(self,
'Select file',
'./',
'Excel Files (*.xls *.xlsx)')
# assign a path to some element
self.label_5.setText(f"{excel_path}")
# we get the path from this element
book = openpyxl.load_workbook(fr"{self.label_5.text()}")
The method you provided works correctly.
import sys
import xlrd
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import QAxWidget
class AxWidget(QWidget):
def __init__(self, *args, **kwargs):
super(AxWidget, self).__init__(*args, **kwargs)
self.resize(800, 600)
layout = QVBoxLayout(self)
self.axWidget = QAxWidget(self)
layout.addWidget(self.axWidget)
layout.addWidget(QPushButton('Select file', self, clicked=self.getxlsbase))
def getxlsbase(self):
filePath_base, _ = QFileDialog.getOpenFileName(self,
'Select file',
'./',
'Excel Files (*.xls *.xlsx)')
print("filePath_base->", filePath_base)
base = xlrd.open_workbook(filePath_base)
print("base->", base)
hoja_base = base.sheet_by_index(0)
print("hoja_base->", hoja_base)
num_row = hoja_base.nrows
print("num_row->", num_row)
num_col = hoja_base.ncols
print("num_col->", num_col)
return self.openOffice(filePath_base, 'Excel.Application')
def openOffice(self, path, app):
self.axWidget.clear()
if not self.axWidget.setControl(app):
return QMessageBox.critical(self, 'Error', 'No installation %s' % app)
self.axWidget.dynamicCall(
'SetVisible (bool Visible)', 'false')
self.axWidget.setProperty('DisplayAlerts', False)
self.axWidget.setControl(path)
def closeEvent(self, event):
self.axWidget.close()
self.axWidget.clear()
self.layout().removeWidget(self.axWidget)
del self.axWidget
super(AxWidget, self).closeEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = AxWidget()
ex.show()
sys.exit(app.exec_())
I'm facing an issue to save a complete state of a Qt window application.
What I'd like to di is save a file which contains everything about the window and then, if I want, I could reload it to obtain the same window with all previous variable in it (reload their values)
For instance, I've this code
import pickle
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class SurfViewer(QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
self.parent = parent
self.centralWidget = QWidget()
self.color = self.centralWidget.palette().color(QPalette.Background)
self.setCentralWidget(self.centralWidget)
self.plotview = QGroupBox(" ")
self.layout_plotview = QVBoxLayout()
self.test = QLineEdit('0.0')
self.Button_Loadstate = QPushButton('Load state')
self.Button_Savestate = QPushButton('Save state')
self.layout_plotview.addWidget(self.test)
self.layout_plotview.addWidget(self.Button_Savestate)
self.layout_plotview.addWidget(self.Button_Loadstate)
self.centralWidget.setLayout(self.layout_plotview)
self.Button_Savestate.clicked.connect(self.Savestate)
self.Button_Loadstate.clicked.connect(self.Loadstate)
def Savestate(self,):
fileName = QFileDialog.getSaveFileName(self,'Save State')
if (fileName[0] == '') :
return
file_pi = open(fileName[0] + '.state', 'wb')
pickle.dump(self, file_pi)
file_pi.close()
return
def Loadstate(self,):
fileName = QFileDialog.getOpenFileName(self,'Load State' , "", "data files (*.state)")
if (fileName[0] == '') :
return
filehandler = open(fileName[0], 'rb')
self = pickle.load(filehandler)
filehandler.close()
return
def main():
app = QApplication(sys.argv)
ex = SurfViewer(app)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
which give me this :
I create a window with a QLineEdit and two buttons (one for saving and one for loading). Then I use pickle to save the self of the SurfViewer class instance in a Savestatefunction. Then I try to reload the previous state with pickle self = pickle.load(filehandler). It seems that it will not be so simple because I cannot assign the self variable.
If anyone could give some insights to perform that without saving every variable by hand.