Pass other functions returned value to QtableView in PYQt5 - pyqt5

I am stuck on the last bit of the code to create a small search engine. So far I have been able to let users do some actions as select a folder where the files to search are stored, create an index, search for keyword and then export excerpt of the text around the keyword to a txt file. This is the layout
And this is the code I have used:
from PyQt5 import QtCore, QtGui, QtWidgets, QtWidgets
from PyQt5.QtWidgets import QHeaderView
import os, os.path
import glob
import os
from PyPDF2 import PdfFileReader, PdfFileWriter
import pdftotext
from whoosh import index
from whoosh.fields import Schema, TEXT, ID, STORED
from whoosh.analysis import RegexTokenizer
from whoosh.analysis import StopFilter
from whoosh import scoring
from whoosh.index import open_dir
from whoosh import qparser
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1126, 879)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(40, 30, 100, 30))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(180, 30, 120, 30))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setGeometry(QtCore.QRect(620, 30, 80, 30))
self.pushButton_3.setObjectName("pushButton_3")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(380, 60, 191, 21))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(40, 90, 50, 21))
self.lineEdit_2.setObjectName("lineEdit_2")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(380, 30, 50, 35))
font = QtGui.QFont()
font.setPointSize(10)
self.label.setFont(font)
self.label.setObjectName("label")
self.label2 = QtWidgets.QLabel(self.centralwidget)
self.label2.setGeometry(QtCore.QRect(40, 70, 150, 16))
font = QtGui.QFont()
font.setPointSize(10)
self.label2.setFont(font)
self.label2.setObjectName("label")
self.tableView = QtWidgets.QTableView(self.centralwidget)
self.tableView.setGeometry(QtCore.QRect(0, 120, 1121, 721))
self.tableView.setObjectName("tableView")
self.horizontal_header = self.tableView.horizontalHeader()
self.vertical_header = self.tableView.verticalHeader()
self.horizontal_header.setSectionResizeMode(
QHeaderView.ResizeToContents
)
self.vertical_header.setSectionResizeMode(
QHeaderView.ResizeToContents
)
self.horizontal_header.setStretchLastSection(True)
self.tableView.showGrid()
self.tableView.wordWrap()
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1126, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.pushButton.clicked.connect(self.open_directory)
self.pushButton_2.clicked.connect(self.createindex)
self.pushButton_3.clicked.connect(self.export)
self.lineEdit.returnPressed.connect(self.search)
def open_directory(self):
self.dialog = QtWidgets.QFileDialog()
self.folder_path = self.dialog.getExistingDirectory(None, "Select Folder")
return self.folder_path
def createindex(self):
os.chdir(self.folder_path)
self.mypdfiles = glob.glob("*.pdf")
#creation of folder for splitted files
MYDIR = ("Splitted")
CHECK_FOLDER = os.path.isdir(MYDIR)
if not CHECK_FOLDER:
os.makedirs(MYDIR)
# save split downloaded file and save into new folder
for self.file in self.mypdfiles:
self.fname = os.path.splitext(os.path.basename(self.file))[0]
self.pdf = PdfFileReader(self.file)
for self.page in range(self.pdf.getNumPages()):
self.pdfwrite = PdfFileWriter()
self.pdfwrite.addPage(self.pdf.getPage(self.page))
self.outputfilename = '{}_page_{}.pdf'.format(self.fname, self.page+1)
with open(os.path.join("./Splitted", self.outputfilename), 'wb') as out:
self.pdfwrite.write(out)
print('Created: {}'.format(self.outputfilename))
#set working directory
os.chdir(self.folder_path + "/Splitted")
self.spltittedfiles = glob.glob("*.pdf")
MYDIR = ("Txt")
CHECK_FOLDER = os.path.isdir(MYDIR)
if not CHECK_FOLDER:
os.makedirs(MYDIR)
# Load your PDF
for self.file in self.spltittedfiles:
with open(self.file, "rb") as f:
self.pdf = pdftotext.PDF(f)
#creation of folder for splitted files
# Save all text to a txt file.
with open(os.path.join("./TXT", os.path.splitext(os.path.basename(self.file))[0] + ".txt") , 'w', encoding = 'utf-8') as f:
f.write("\n\n".join(self.pdf))
f.close()
os.chdir(self.folder_path)
MYDIR = ("indexdir")
CHECK_FOLDER = os.path.isdir(MYDIR)
if not CHECK_FOLDER:
os.makedirs(MYDIR)
self.my_analyzer = RegexTokenizer()| StopFilter(lang = "en")
self.schema = Schema(title=TEXT(stored=True),path=ID(stored=True),
content=TEXT(analyzer = self.my_analyzer),
textdata=TEXT(stored=True))
# set an index writer to add document as per schema
self.ix = index.create_in("indexdir",self.schema)
self.writer = self.ix.writer()
self.filepaths = [os.path.join("./Splitted/Txt",i) for i in os.listdir("./Splitted/Txt")]
for path in self.filepaths:
self.fp = open(path, "r", encoding='utf-8')
self.text = self.fp.read()
self.writer.add_document(title = os.path.splitext(os.path.basename(path))[0] , path=path, content=self.text,textdata=self.text)
self.fp.close()
self.writer.commit()
def search(self):
os.chdir(self.folder_path)
self.ix = open_dir("indexdir")
MYDIR = ("Results")
CHECK_FOLDER = os.path.isdir(MYDIR)
if not CHECK_FOLDER:
os.makedirs(MYDIR)
self.text = self.lineEdit.text()
self.query_str = self.text
self.query = qparser.QueryParser("textdata", schema = self.ix.schema)
self.q = self.query.parse(self.query_str)
self.topN = self.lineEdit_2.text()
if self.lineEdit_2.text() == "":
self.topN = 1000
else:
self.topN = int(self.lineEdit_2.text())
with self.ix.searcher(weighting=scoring.Frequency) as searcher:
self.results = searcher.search(self.q, terms=True, limit=self.topN)
for self.i in range(self.topN):
print(self.results[self.i]['title'], self.results[self.i]['textdata'])
def export(self):
with self.ix.searcher(weighting=scoring.Frequency) as searcher:
self.results = searcher.search(self.q, terms=True, limit= None)
for self.i in range(self.topN):
with open(os.path.join(self.folder_path, self.text + ".txt"), 'a') as f:
print(self.results[self.i]['title'], self.results[self.i]['textdata'], file=f)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Search Text"))
self.pushButton.setText(_translate("MainWindow", "Select Folder"))
self.pushButton_2.setText(_translate("MainWindow", "Create Database"))
self.pushButton_3.setText(_translate("MainWindow", "Export"))
self.label.setText(_translate("MainWindow", "Search"))
self.label2.setText(_translate("MainWindow", "Top Results"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
What I want to do now is to show the results also in the table. I have been trying to understand how to "send" the returned value of the search function to the table and how to show it. It should have two columns: File_Page and Content and as many rows as top results selected. Each row should then show the file with hit and the text of interest like this:
So far I have been able to just set to parameter of the table, but not much more.
Is there any mean to let the table how the results without pushing any other button? As I have so far understood, is it possible to trigger the same function from different places of the code but I did not find the opposite, that is to activate two functions with just one signal
I have found lots of examples but none suits the objective. I am still learning how to use Python and I have never used C++.

Use other signal to trigger layoutChanged. i.e. QLineEdit's signal.
Mind me if I understood your question wrong, assuming you want to update search results as soon as you type something in Search field.
In that case, here's neat working example demonstrating immediate searching on 5 entries:
from PySide2.QtWidgets import QWidget, QApplication, QPushButton, QVBoxLayout, QLineEdit
from PySide2.QtCore import QAbstractTableModel, QModelIndex, Qt, QObject
from PySide2.QtWidgets import QTableView
import sys
class Table(QAbstractTableModel):
def __init__(self, data):
super().__init__()
self._data = data
def data(self, index: QModelIndex, role: int = ...):
if role == Qt.DisplayRole:
return self._data[index.row()][index.column()]
def rowCount(self, parent: QModelIndex = ...) -> int:
return len(self._data)
def columnCount(self, parent: QModelIndex = ...) -> int:
return len(self._data[0])
def overWriteData(self, new_list):
self._data = new_list
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.table = QTableView()
self.line = QLineEdit()
self.layout = QVBoxLayout()
self.layout.addWidget(self.table)
self.layout.addWidget(self.line)
self.data = [('stack overflow', 'some_fancy_data'),
('stack overflow', 'some_fancy_data'),
('stack underflow', 'some_fancy_data'),
('Server Fault', 'some_fancy_data'),
('Ask Ubuntu', 'some_fancy_data')]
self.model = Table(self.data)
self.table.setModel(self.model)
self.setLayout(self.layout)
self.line.textChanged.connect(self.update)
def update(self):
filtered = [i for i in self.data if self.line.text() in i[0]]
if filtered:
self.model.overWriteData(filtered)
self.model.layoutChanged.emit()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

I have shifted to Qtable Widget, created a new function (datatable) and called it from setup UI.
This is the new setupUI:
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1126, 879)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(40, 30, 100, 30))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(180, 30, 120, 30))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setGeometry(QtCore.QRect(620, 30, 80, 30))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_4.setGeometry(QtCore.QRect(180, 80, 80, 30))
self.pushButton_4.setObjectName("pushButton_4")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(380, 60, 191, 21))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(40, 90, 50, 21))
self.lineEdit_2.setObjectName("lineEdit_2")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(380, 30, 50, 35))
font = QtGui.QFont()
font.setPointSize(10)
self.label.setFont(font)
self.label.setObjectName("label")
self.label2 = QtWidgets.QLabel(self.centralwidget)
self.label2.setGeometry(QtCore.QRect(40, 70, 150, 16))
font = QtGui.QFont()
font.setPointSize(10)
self.label2.setFont(font)
self.label2.setObjectName("label")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(0, 120, 1121, 721))
self.tableWidget.setObjectName("tableWidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1126, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.pushButton.clicked.connect(self.open_directory)
self.pushButton_2.clicked.connect(self.createindex)
self.pushButton_3.clicked.connect(self.export)
self.pushButton_4.clicked.connect(self.OCR)
self.lineEdit.returnPressed.connect(self.search)
self.lineEdit.returnPressed.connect(self.datatable)
And this is the function that takes the data returned from another function within the class.
numrows = len(self.data)
numcols = len(self.data[0])
self.tableWidget.setColumnCount(numcols)
self.tableWidget.setRowCount(numrows)
self.tableWidget.setHorizontalHeaderLabels((list(self.data[0].keys())))
self.tableWidget.resizeColumnsToContents()
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
for row in range(numrows):
for column in range(numcols):
item = (list(self.data[row].values())[column])
self.tableWidget.setItem(row, column, QTableWidgetItem(item)) ```

Related

Pyqt5 qthread signal and pyqtslot

How to send data to thread is running by pyqt as the code below?
I think it would be using pyqtslot, but I don't know how to use.
I'm trying to use the pyqt qthread for multithreading program.
In the code, there are two different workers instance. I try to use signal and slot for data share. but it seemed that the signal is blocked until one of the qthread is finished.
this is the code.
gui.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(641, 204)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.Button_start_1 = QtWidgets.QPushButton(self.centralwidget)
self.Button_start_1.setGeometry(QtCore.QRect(30, 20, 81, 41))
self.Button_start_1.setObjectName("Button_start_1")
self.Button_start_2 = QtWidgets.QPushButton(self.centralwidget)
self.Button_start_2.setGeometry(QtCore.QRect(30, 70, 81, 41))
self.Button_start_2.setObjectName("Button_start_2")
self.Button_stop_1 = QtWidgets.QPushButton(self.centralwidget)
self.Button_stop_1.setGeometry(QtCore.QRect(150, 20, 75, 41))
self.Button_stop_1.setObjectName("Button_stop_1")
self.Button_stop_2 = QtWidgets.QPushButton(self.centralwidget)
self.Button_stop_2.setGeometry(QtCore.QRect(150, 70, 75, 41))
self.Button_stop_2.setObjectName("Button_stop_2")
self.lcdNumber_1 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_1.setGeometry(QtCore.QRect(250, 20, 151, 41))
self.lcdNumber_1.setObjectName("lcdNumber_1")
self.lcdNumber_2 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber_2.setGeometry(QtCore.QRect(250, 70, 151, 41))
self.lcdNumber_2.setObjectName("lcdNumber_2")
self.Button_pause_thread_1 = QtWidgets.QPushButton(self.centralwidget)
self.Button_pause_thread_1.setGeometry(QtCore.QRect(420, 20, 121, 41))
self.Button_pause_thread_1.setObjectName("Button_pause_thread_1")
self.Button_pause_thread_2 = QtWidgets.QPushButton(self.centralwidget)
self.Button_pause_thread_2.setGeometry(QtCore.QRect(420, 70, 121, 41))
self.Button_pause_thread_2.setObjectName("Button_pause_thread_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 641, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.Button_start_1.setText(_translate("MainWindow", "Start thread1"))
self.Button_start_2.setText(_translate("MainWindow", "Start thread2"))
self.Button_stop_1.setText(_translate("MainWindow", "Stop thread 1"))
self.Button_stop_2.setText(_translate("MainWindow", "Stop thread 1"))
self.Button_pause_thread_1.setText(_translate("MainWindow", "Pause thread 1"))
self.Button_pause_thread_2.setText(_translate("MainWindow", "Pause thread 2"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Main.py
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import pyqtSignal
from PyQt5 import QtCore
import time
from gui import Ui_MainWindow
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.uic = Ui_MainWindow()
self.uic.setupUi(self)
self.thread = {}
self.uic.Button_start_1.clicked.connect(self.start_worker_1)
self.uic.Button_start_2.clicked.connect(self.start_worker_2)
self.uic.Button_stop_1.clicked.connect(self.stop_worker_1)
self.uic.Button_stop_2.clicked.connect(self.stop_worker_2)
def start_worker_1(self):
self.thread[1] = ThreadClass(index=1)
self.thread[1].start()
self.thread[1].signal.connect(self.my_function)
self.uic.Button_start_1.setEnabled(False)
self.uic.Button_stop_1.setEnabled(True)
def start_worker_2(self):
self.thread[2] = ThreadClass(index=2)
self.thread[2].start()
self.thread[2].signal.connect(self.my_function)
self.uic.Button_start_2.setEnabled(False)
self.uic.Button_stop_2.setEnabled(True)
def stop_worker_1(self):
self.thread[1].stop()
self.uic.Button_stop_1.setEnabled(False)
self.uic.Button_start_1.setEnabled(True)
def stop_worker_2(self):
self.thread[2].stop()
self.uic.Button_stop_2.setEnabled(False)
self.uic.Button_start_2.setEnabled(True)
def my_function(self, counter):
m = counter
i = self.sender().index
if i == 1:
self.uic.lcdNumber_1.display(m)
if i == 2:
self.uic.lcdNumber_2.display(m)
class ThreadClass(QtCore.QThread):
signal = pyqtSignal(int)
def __init__(self, index=0):
super().__init__()
self.index = index
def run(self):
print('Starting thread...', self.index)
counter = 0
while True:
counter += 1
print(counter)
time.sleep(1)
self.signal.emit(counter)
def stop(self):
print('Stopping thread...', self.index)
self.terminate()
def get_value_from_button(self):
print("value of thread ")
if __name__ == "__main__":
app = QApplication(sys.argv)
main_win = MainWindow()
main_win.show()
sys.exit(app.exec())
I need to get data at get_value_from_button(self) function, when I press the button.

How to add a live (updating) graph to my PyQt5 Window using Serial?

I am writting a program that's supposed to receive 4 random values from my Arduino every second and create an updating bar chart with them. I then want to create a PyQt5 Window to show that bar chart. I was sucessful at reading the values coming from my Arduino and using them to create the bar chart. However, since I'm a beginner when it comes to GUI/Arduino, I have no clue how to add that bar chart to my PyQt Window. I'd appreciate if you could help me with that.
Here's my Arduino code:
void setup() {
Serial.begin(115200);
}
void loop() {
float nb1 = random(0, 100);
float nb2 = random(0, 100);
float nb3 = random(0, 100);
float nb4 = random(0, 100);
Serial.print(nb1);
Serial.print(" , ");
Serial.print(nb2);
Serial.print(" , ");
Serial.print(nb3);
Serial.print(" , ");
Serial.println(nb4);
delay(1000);
}
and here's what the graph should look like (the titles and labels are in french, but don't mind that):
import serial
import numpy
import matplotlib.pyplot as plt
from drawnow import *
plt.ion()
def make_figure():
plt.ylim(0, 100)
plt.title("Titre que tu veux")
plt.tick_params(axis = 'x', which = 'both', bottom = False, top = False, labelbottom = False)
plt.hlines(16, -0.5, 0.5, color = 'g')
plt.ylabel("Nom de la variable")
plt.bar(0, nb1, color = 'b')
plt.bar(2, nb2, color = 'b')
plt.hlines(42, 1.5, 2.5, color = 'g')
plt.bar(4, nb3, color = 'b')
plt.hlines(32, 3.5, 4.5, color = 'g')
plt.bar(6, nb4, color = 'b')
plt.hlines(80, 5.5, 6.5, color = 'g')
with serial.Serial('COM3', baudrate = 115200) as ser:
while True:
while (ser.inWaiting() == 0):
pass
string_received = ser.readline().decode().strip('\r\n')
dataArray = string_received.split(" , ")
nb1 = float(dataArray[0])
nb2 = float(dataArray[1])
nb3 = float(dataArray[2])
nb4 = float(dataArray[3])
drawnow(make_figure)
plt.pause(0.000001)
Now, here is what my Window should look like, but replace the static chart with a dynamic one (don't mind the buttons, they're not meant to do anything right now):
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
super(MplCanvas, self).__init__(fig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("Titre que tu veux")
MainWindow.resize(1510, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushgetMax = QtWidgets.QPushButton(self.centralwidget)
self.pushgetMax.setGeometry(QtCore.QRect(1240, 30, 93, 28))
self.pushgetMax.setObjectName("pushgetMax")
self.pushAll = QtWidgets.QPushButton(self.centralwidget)
self.pushAll.setGeometry(QtCore.QRect(1350, 30, 93, 28))
self.pushAll.setObjectName("pushAll")
self.pushButton1 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton1.setGeometry(QtCore.QRect(1240, 70, 93, 28))
self.pushButton1.setObjectName("pushButton1")
self.pushButton2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton2.setGeometry(QtCore.QRect(1350, 70, 93, 28))
self.pushButton2.setObjectName("pushButton2")
self.pushButton3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton3.setGeometry(QtCore.QRect(1240, 110, 93, 28))
self.pushButton3.setObjectName("pushButton3")
self.pushButton_6 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_6.setGeometry(QtCore.QRect(1350, 110, 93, 28))
self.pushButton_6.setObjectName("pushButton_6")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 10, 1191, 531))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
barre1 = MplCanvas(self, width=5, height=4, dpi=100)
barre1.axes.set_ylim([0, 100])
barre1.axes.set_title('Titre 1')
barre1.axes.tick_params(axis = 'x', which = 'both', bottom = False, top = False, labelbottom = False)
barre1.axes.bar(0, 22, color = 'b')
barre1.axes.hlines(25, -0.5, 0.5, color = 'g')
barre1.axes.bar(2, 50, color = 'b')
barre1.axes.hlines(60, 1.5, 2.5, color = 'g')
barre1.axes.bar(4, 32, color = 'b')
barre1.axes.hlines(50, 3.5, 4.5, color = 'g')
barre1.axes.bar(6, 81, color = 'b')
barre1.axes.hlines(70, 5.5, 6.5, color = 'g')
self.horizontalLayout.addWidget(barre1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1510, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushgetMax.setText(_translate("MainWindow", "GetMax"))
self.pushAll.setText(_translate("MainWindow", "All"))
self.pushButton1.setText(_translate("MainWindow", "1"))
self.pushButton2.setText(_translate("MainWindow", "2"))
self.pushButton3.setText(_translate("MainWindow", "3"))
self.pushButton_6.setText(_translate("MainWindow", "4"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
If you are going to use PyQt5 then forget about pyplot since you have to use the respective canvas. On the other hand do not use pyserial since it is better to use QSerialPort since it uses the Qt eventloop.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, QtSerialPort
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
class SerialPortManager(QtCore.QObject):
dataChanged = QtCore.pyqtSignal(list)
def __init__(self, parent=None):
super().__init__(parent)
self._serial = QtSerialPort.QSerialPort(baudRate=115200)
self.serial.setPortName("COM3")
self.serial.readyRead.connect(self.on_ready_read)
#property
def serial(self):
return self._serial
def start(self):
self.serial.open(QtCore.QIODevice.ReadOnly)
#QtCore.pyqtSlot()
def on_ready_read(self):
if self.serial.canReadLine():
line = self.serial.readLine().data().decode()
values = line.strip().split(",")
try:
data = list(map(float, values))
except ValueError as e:
print("error", e)
else:
self.dataChanged.emit(data)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
fig = Figure(figsize=(5, 4), dpi=100)
self.canvas = FigureCanvas(fig)
self.max_button = QtWidgets.QPushButton(self.tr("GetMax"))
self.all_button = QtWidgets.QPushButton(self.tr("All"))
self.one_button = QtWidgets.QPushButton(self.tr("1"))
self.two_button = QtWidgets.QPushButton(self.tr("2"))
self.three_button = QtWidgets.QPushButton(self.tr("3"))
self.four_button = QtWidgets.QPushButton(self.tr("4"))
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
hlay = QtWidgets.QHBoxLayout(central_widget)
hlay.addWidget(self.canvas, stretch=1)
grid_layout = QtWidgets.QGridLayout()
grid_layout.addWidget(self.max_button, 0, 0)
grid_layout.addWidget(self.all_button, 0, 1)
grid_layout.addWidget(self.one_button, 1, 0)
grid_layout.addWidget(self.two_button, 1, 1)
grid_layout.addWidget(self.three_button, 2, 0)
grid_layout.addWidget(self.four_button, 2, 1)
vlay = QtWidgets.QVBoxLayout()
vlay.addLayout(grid_layout)
vlay.addStretch()
hlay.addLayout(vlay)
self.axes = self.canvas.figure.add_subplot(111)
self.axes.set_ylim([0, 100])
self.axes.set_title("Titre 1")
self.axes.tick_params(
axis="x", which="both", bottom=False, top=False, labelbottom=False
)
self.axes.hlines(25, -0.5, 0.5, color="g")
self.axes.hlines(60, 1.5, 2.5, color="g")
self.axes.hlines(50, 3.5, 4.5, color="g")
self.axes.hlines(70, 5.5, 6.5, color="g")
self.containers = []
self.update_bars([0, 0, 0, 0])
self.resize(640, 480)
#QtCore.pyqtSlot(list)
def update_bars(self, values):
if len(values) == 4:
[c.remove() for c in self.containers]
self.containers = []
for index, value in zip((0, 2, 4, 6), values):
c = self.axes.bar(index, value, color="b")
self.containers.append(c)
self.canvas.draw()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
manager = SerialPortManager()
manager.dataChanged.connect(w.update_bars)
manager.start()
sys.exit(app.exec_())

CheckBox to a variables. PyQt5

How can I link checkbox to the variable under pushbutton?
The checkbox will return either 0 or 1 for the variable F which will affect the calculation output.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 394)
self.spinBox = QtWidgets.QSpinBox(Dialog)
self.spinBox.setGeometry(QtCore.QRect(60, 120, 48, 24))
self.spinBox.setObjectName("spinBox")
self.spinBox.setRange(1, 200)
self.spinBox.setValue(0)
self.checkBox = QtWidgets.QCheckBox(Dialog)
self.checkBox.setGeometry(QtCore.QRect(60, 160, 87, 20))
self.checkBox.setObjectName("checkBox")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(50, 190, 113, 32))
self.pushButton.setObjectName("pushButton")
self.lcdNumber = QtWidgets.QLCDNumber(Dialog)
self.lcdNumber.setGeometry(QtCore.QRect(90, 230, 113, 32))
self.lcdNumber.setObjectName("lcdNumber")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.pushButton.clicked.connect(self.pushButton_handler)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.checkBox.setText(_translate("Dialog", "CheckBox"))
self.pushButton.setText(_translate("Dialog", "PushButton"))
def pushButton_handler(self, state):
A1 = self.spinBox.value()
F= ??? #F to be equal to 0 if check box checked or 1 if
check box unchecked.
i=A1*F
app.processEvents()'
self.lcdNumber.display(i)
QCheckBox::stateChanged(int state)
This signal is emitted whenever the checkbox's state changes, i.e., whenever the user checks or unchecks it.
state contains the checkbox's new Qt::CheckState.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 394)
self.spinBox = QtWidgets.QSpinBox(Dialog)
self.spinBox.setGeometry(QtCore.QRect(60, 120, 48, 24))
self.spinBox.setObjectName("spinBox")
self.spinBox.setRange(1, 200)
self.spinBox.setValue(0)
self.checkBox = QtWidgets.QCheckBox(Dialog)
self.checkBox.setGeometry(QtCore.QRect(60, 160, 87, 20))
self.checkBox.setObjectName("checkBox")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(50, 190, 113, 32))
self.pushButton.setObjectName("pushButton")
self.lcdNumber = QtWidgets.QLCDNumber(Dialog)
self.lcdNumber.setGeometry(QtCore.QRect(90, 230, 113, 32))
self.lcdNumber.setObjectName("lcdNumber")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.pushButton.clicked.connect(self.pushButton_handler)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.checkBox.setText(_translate("Dialog", "CheckBox"))
self.pushButton.setText(_translate("Dialog", "PushButton"))
class Example(QtWidgets.QDialog, Ui_Dialog): # +
def __init__(self):
super(Example, self).__init__()
self.setupUi(self)
self.checkBox.stateChanged.connect(self.selectCheckBox) # +++
self.F = 1 # +
def pushButton_handler(self, state):
A1 = self.spinBox.value()
# F = #??? #F to be equal to 0 if check box checked or 1 if check box unchecked.
i = A1 * self.F
# ? app.processEvents()'
self.lcdNumber.display(i)
def selectCheckBox(self, toggle): # +++
if toggle == QtCore.Qt.Checked:
self.F = 0
else:
self.F = 1
if __name__ == "__main__":
app = QApplication(sys.argv)
default_font = QFont()
default_font.setPointSize(15)
app.setFont(default_font)
w = Example()
w.resize(220, 300)
w.show()
sys.exit(app.exec_())

How to scale background image to cover MainWindow in PyQt5

I trying to learn PyQt5 so it might a noobie question, but I search a lot and I couldn't find a solution.
I wrinting a sample code showing a countdow to a defined datetime and now it looks like in the image below:
I need to resize the image to cover the app, atm I have a window 300x200 and background image 2400x1800.
I also need the background to resize on MainWindow resize. At first glance css property background-size is not supported, border-image would strech the image.
OS: Windows 7-10 (not a choise)
Python: 3.4.3
PyQt: 5.5
Current code (not working)
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtCore import QObject, pyqtSignal, QTimer
import design
import sys
from datetime import datetime, timedelta
# UI base class is inherited from design.Ui_MainWindow
class Counter(QtWidgets.QMainWindow, design.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
# applying background image
self.background = QtGui.QPixmap("./assets/img/trecime.jpg")
palette = QtGui.QPalette()
palette.setBrush(QtGui.QPalette.Background,QtGui.QBrush(self.background).scale(self.size()))
self.MainWindow.setPalette(palette)
# custom colors for QLCDWidgets
lcdPalette = self.dayCount.palette()
lcdPalette.setColor(lcdPalette.WindowText, QtGui.QColor(255,0,0, 200))
lcdPalette.setColor(lcdPalette.Background, QtGui.QColor(0, 0, 0, 0))
lcdPalette.setColor(lcdPalette.Light, QtGui.QColor(200, 0, 0, 120))
lcdPalette.setColor(lcdPalette.Dark, QtGui.QColor(100, 0, 0, 150))
self.dayCount.setPalette(lcdPalette)
lcdPalette.setColor(lcdPalette.WindowText, QtGui.QColor(255,255,255, 200))
lcdPalette.setColor(lcdPalette.Light, QtGui.QColor(200, 0, 0, 0))
lcdPalette.setColor(lcdPalette.Dark, QtGui.QColor(200, 0, 0, 0))
self.timeCount.setPalette(lcdPalette)
# init Qtimer
self.timer = QTimer()
self.timer.timeout.connect(self.update_timer)
self.timer.start(200)
# config final date
self.finalDatetime = datetime(2016, 11, 30, 14, 00)
def resizeEvent(self, resizeEvent):
print('resized')
def update_timer(self):
currentDatetime = datetime.today()
delta = self.finalDatetime - currentDatetime
(days, hours, minutes) = days_hours_minutes(delta)
self.dayCount.display(days)
# blinking colon
separator = ":" if delta.microseconds < 799999 else ' '
self.timeCount.display('%02d%s%02d' % (hours, separator, minutes))
def days_hours_minutes(td):
return td.days, td.seconds//3600, (td.seconds//60)%60
def main():
app = QtWidgets.QApplication(sys.argv)
counter = Counter()
counter.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
pyqt style sheet can be used for this resizing
try
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self,MainWindow):
super().__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
MainWindow.setObjectName("MainWindow")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralWidget)
self.horizontalLayout_2.setContentsMargins(11, 11, 11, 11)
self.horizontalLayout_2.setSpacing(6)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSpacing(6)
self.horizontalLayout.setObjectName("horizontalLayout")
self.start_button = QtWidgets.QPushButton(self.centralWidget)
self.start_button.setObjectName("start_button")
self.horizontalLayout.addWidget(self.start_button)
self.stop_button = QtWidgets.QPushButton(self.centralWidget)
self.stop_button.setObjectName("stop_button")
self.horizontalLayout.addWidget(self.stop_button)
self.horizontalLayout_2.addLayout(self.horizontalLayout)
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
self.menuBar.setObjectName("menuBar")
MainWindow.setMenuBar(self.menuBar)
self.mainToolBar = QtWidgets.QToolBar(MainWindow)
self.mainToolBar.setObjectName("mainToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.start_button.setText(_translate("MainWindow", "Start"))
self.stop_button.setText(_translate("MainWindow", "Stop"))
stylesheet = """
MainWindow {
border-image: url("The_Project_logo.png");
background-repeat: no-repeat;
background-position: center;
}
"""
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
app.setStyleSheet(stylesheet) # <---
window = MainWindow()
window.resize(640, 640)
window.show()
sys.exit(app.exec_())

How can i save the content of lable entry while click on a switch using pygtk

import gtk
class PyApp(gtk.Window):
def __init__(self):
super(PyApp, self).__init__()
self.set_title("Entry")
self.set_size_request(300, 300)
self.set_position(gtk.WIN_POS_CENTER)
fixed = gtk.Fixed()
self.label = gtk.Label("Entry")
fixed.put(self.label, 40, 40)
entry = gtk.Entry()
fixed.put(entry, 80, 40)
self.button1 = gtk.Button(" OK ")
button1 = gtk.Button(stock=gtk.STOCK_CLOSE)
fixed.put(self.button1, 130, 90)
self.connect("destroy", gtk.main_quit)
self.add(fixed)
self.show_all()
PyApp()
gtk.main()
How to save this label entry as a text file?
If you want to save the text of the GtkEntry after clicking the button, you have to connect to the clicked signal:
import gtk
class PyApp(gtk.Window):
def __init__(self):
super(PyApp, self).__init__()
self.set_title("Entry")
self.set_size_request(300, 300)
self.set_position(gtk.WIN_POS_CENTER)
fixed = gtk.Fixed()
self.label = gtk.Label("Entry")
fixed.put(self.label, 40, 40)
self.entry = gtk.Entry()
fixed.put(self.entry, 80, 40)
button1 = gtk.Button("OK")
button1.connect('clicked', self.button_clicked)
fixed.put(button1, 130, 90)
self.connect("destroy", gtk.main_quit)
self.add(fixed)
self.show_all()
def button_clicked(self, widget):
with open('entry.txt', 'w') as f:
f.write(self.entry.get_text())
PyApp()
gtk.main()