PyQt5 QMainWindow | Returning to Main Window (Dashboard/Home Screen) Using QToolBar Button - pyqt5

I am using a QToolBar for Navigating from page to page. Obviously I am using QMainWindow. The first issue I had was getting QWidgets/layouts on the QMainWindow. I was able to solve this issue with the solution used for this StackOverflow question:
PYQT5 QMainWindow setCentralWidget consisting of multiple box layouts
The solution to the question above does display the layout when the application is first started, but when you click another ToolBar button, and then click the Dashboard ToolBar button it does not return to the layout on the QMainWindow screen.
Start of Application:
TButton One Screen:
In the dashboard() function you will see everything I have tried to get back to the QMainWindow layout. All the other buttons work fine. I just can't seem to figure out how to get back to the layout on the QMainWindow.
The line of code used in the dashboard() function simply displays a blank screen as shown below
Black Dashboard:
How can I return to the layout on the QMainWindow using the Dashboard ToolBar button?
Your help will be greatly appreciated.
Code:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import QtGui
from PyQt5.QtCore import *
import sys
class ApplicationWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PyQt5 QMainWindow Example")
self.setWindowIcon(QtGui.QIcon("IMAGES/python.ico"))
self.resize(1350, 750)
self.main_widget = QWidget(self)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
self.gui()
def gui(self):
self.main_tool_bar()
self.widgets()
self.layouts()
def main_tool_bar(self):
tool_bar = QToolBar()
tool_bar.setStyleSheet("background-color: #020000; color: #FFFFFF;")
self.addToolBar(Qt.LeftToolBarArea, tool_bar)
tool_bar.setMovable(False)
tool_bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
tool_bar.setIconSize(QSize(40, 40))
dashboard_tool_bar_btn = QAction(QtGui.QIcon("IMAGES/dashboard.png"), "Dashboard", self)
dashboard_tool_bar_btn.triggered.connect(self.dashboard)
tool_bar_one_btn = QAction(QtGui.QIcon("IMAGES/tool_one.png"), "TButton One", self)
tool_bar_one_btn.triggered.connect(self.button_one)
tool_bar_two_btn = QAction(QtGui.QIcon("IMAGES/tool_two.png"), "TButton Two", self)
tool_bar_two_btn.triggered.connect(self.button_two)
tool_bar_three_btn = QAction(QtGui.QIcon("IMAGES/tool_three.png"), "TButton Three", self)
tool_bar_three_btn.triggered.connect(self.button_three)
tool_bar_four_btn = QAction(QtGui.QIcon("IMAGES/tool_four.png"), "TButton Four", self)
tool_bar_four_btn.triggered.connect(self.button_four)
tool_bar.addAction(dashboard_tool_bar_btn)
tool_bar.addAction(tool_bar_one_btn)
tool_bar.addAction(tool_bar_two_btn)
tool_bar.addAction(tool_bar_three_btn)
tool_bar.addAction(tool_bar_four_btn)
def widgets(self):
# l = QVBoxLayout(self.main_widget)
# l.addWidget(self.ldt_one)
# l.addWidget(self.ldt_two)
# Snippet 3
# x = QHBoxLayout() # self.main_widget) # new
# x.addWidget(b1) # new + b1
# x.addWidget(b2) # new + b2
#
# l.addLayout(x)
# l.addStretch()
self.header_lbl = QLabel("QMainWindow Example")
self.header_lbl.setStyleSheet("color: green")
self.title_lbl = QLabel("Dashboard")
self.title_lbl.setStyleSheet("font-size: 12pt; font-weight: Normal;")
self.ldt_one = QLineEdit()
self.ldt_two = QLineEdit()
self.b1 = QPushButton("Button 1") # new
self.b1.clicked.connect(self.lineedit_one)
self.b2 = QPushButton("Button 2") # new
self.b2.clicked.connect(self.lineedit_two)
def layouts(self):
self.l = QVBoxLayout(self.main_widget)
self.header_layout = QHBoxLayout()
self.title_layout = QHBoxLayout()
self.x = QHBoxLayout()
self.header_layout.addWidget(self.header_lbl)
self.header_layout.setContentsMargins(10, 15, 0, 5)
self.header_layout.addStretch()
self.title_layout.addWidget(self.title_lbl)
self.title_layout.setContentsMargins(10, 0, 0, 0)
self.title_layout.addStretch()
self.l.addLayout(self.header_layout)
self.l.addLayout(self.title_layout)
self.l.addWidget(self.ldt_one)
self.l.addWidget(self.ldt_two)
self.x.addWidget(self.b1) # new + b1
self.x.addWidget(self.b2) # new + b2
self.l.addLayout(self.x)
self.l.addStretch()
self.setLayout(self.l)
def dashboard(self):
# self.gui()
# self.show(self.main_widget)
# self.setCentralWidget(self.main_widget)
# self.setCentralWidget(self.gui())
# app_window = ApplicationWindow()
# app_window.show()
# app_window = ApplicationWindow(self.main_widget)
# app_window.show()
# self.setCentralWidget(app_window)
# self.main_widget.show()
# app_ = ApplicationWindow()
# app_.gui()
self.setCentralWidget(self.show())
def button_one(self):
btn_one = ButtonOne()
self.setCentralWidget(btn_one)
def button_two(self):
btn_two = ButtonTwo()
self.setCentralWidget(btn_two)
def button_three(self):
btn_three = ButtonThree()
self.setCentralWidget(btn_three)
def button_four(self):
btn_four = ButtonFour()
self.setCentralWidget(btn_four)
def lineedit_one(self):
self.ldt_one.setText("Line Edit One")
def lineedit_two(self):
self.ldt_two.setText("Line Edit Two")
class ButtonOne(QWidget):
def __init__(self):
super().__init__()
self.gui()
def gui(self):
self.widgets()
self.layouts()
def widgets(self):
self.header_lbl = QLabel("QMainWindow Example")
self.header_lbl.setStyleSheet("color: green")
self.title_lbl = QLabel("Tool Button One")
self.title_lbl.setStyleSheet("font-size: 12pt; font-weight: Normal;")
def layouts(self):
self.main_layout = QVBoxLayout()
self.header_layout = QHBoxLayout()
self.title_layout = QHBoxLayout()
self.header_layout.addWidget(self.header_lbl)
self.header_layout.setContentsMargins(10, 15, 0, 5)
self.header_layout.addStretch()
self.title_layout.addWidget(self.title_lbl)
self.title_layout.setContentsMargins(10, 0, 0, 0)
self.title_layout.addStretch()
self.main_layout.addLayout(self.header_layout)
self.main_layout.addLayout(self.title_layout)
self.main_layout.addStretch()
self.setLayout(self.main_layout)
class ButtonTwo(QWidget):
def __init__(self):
super().__init__()
self.gui()
def gui(self):
self.widgets()
self.layouts()
def widgets(self):
self.header_lbl = QLabel("QMainWindow Example")
self.header_lbl.setStyleSheet("color: red")
self.title_lbl = QLabel("Tool Button Two")
self.title_lbl.setStyleSheet("font-size: 12pt; font-weight: Normal;")
def layouts(self):
self.main_layout = QVBoxLayout()
self.header_layout = QHBoxLayout()
self.title_layout = QHBoxLayout()
self.table_layout = QVBoxLayout()
self.header_layout.addWidget(self.header_lbl)
self.header_layout.setContentsMargins(10, 15, 0, 5)
self.header_layout.addStretch()
self.title_layout.addWidget(self.title_lbl)
self.title_layout.setContentsMargins(10, 0, 0, 0)
self.title_layout.addStretch()
self.main_layout.addLayout(self.header_layout)
self.main_layout.addLayout(self.title_layout)
self.main_layout.addStretch()
self.setLayout(self.main_layout)
class ButtonThree(QWidget):
def __init__(self):
super().__init__()
self.gui()
def gui(self):
self.widgets()
self.layouts()
def widgets(self):
self.header_lbl = QLabel("QMainWindow Example")
self.header_lbl.setStyleSheet("color: #2479E6")
self.title_lbl = QLabel("Tool Button Three")
self.title_lbl.setStyleSheet("font-size: 12pt; font-weight: Normal;")
def layouts(self):
self.main_layout = QVBoxLayout()
self.header_layout = QHBoxLayout()
self.title_layout = QHBoxLayout()
self.table_layout = QVBoxLayout()
self.header_layout.addWidget(self.header_lbl)
self.header_layout.setContentsMargins(10, 15, 0, 5)
self.header_layout.addStretch()
self.title_layout.addWidget(self.title_lbl)
self.title_layout.setContentsMargins(10, 0, 0, 0)
self.title_layout.addStretch()
self.main_layout.addLayout(self.header_layout)
self.main_layout.addLayout(self.title_layout)
self.main_layout.addStretch()
self.setLayout(self.main_layout)
class ButtonFour(QWidget):
def __init__(self):
super().__init__()
self.gui()
def gui(self):
self.widgets()
self.layouts()
def widgets(self):
self.header_lbl = QLabel("QMainWindow Example")
self.header_lbl.setStyleSheet("color: orange")
self.title_lbl = QLabel("Tool Button Four")
self.title_lbl.setStyleSheet("font-size: 12pt; font-weight: Normal;")
def layouts(self):
self.main_layout = QVBoxLayout()
self.header_layout = QHBoxLayout()
self.title_layout = QHBoxLayout()
self.table_layout = QVBoxLayout()
self.header_layout.addWidget(self.header_lbl)
self.header_layout.setContentsMargins(10, 15, 0, 5)
self.header_layout.addStretch()
self.title_layout.addWidget(self.title_lbl)
self.title_layout.setContentsMargins(10, 0, 0, 0)
self.title_layout.addStretch()
self.main_layout.addLayout(self.header_layout)
self.main_layout.addLayout(self.title_layout)
self.main_layout.addStretch()
self.setLayout(self.main_layout)
def main():
App = QApplication(sys.argv)
App.setStyleSheet(
'''
QToolButton {
margin-top: 5px;
padding-top: 5px;
}
QLabel {
font-family: Times;
font-size: 26pt;
font-weight: Bold;
color: #000000;
}
'''
)
main_window = ApplicationWindow()
main_window.show()
sys.exit(App.exec_())
if __name__ == "__main__":
main()
# app = QApplication(sys.argv)
# MainWindow = ApplicationWindow()
# MainWindow.show()
# sys.exit(app.exec_())

Related

Pass other functions returned value to QtableView in 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)) ```

How to delete old plot on Matplotlib figure embedded in PyQt5?

I am using matplotlib figure embedded in pyqt5 to draw a frame taking the height and the width from line edit entries.It works well but when I change the values inside the line edits and click on the push button it will draw another frame over the previous one. I have tried plt.gcf().clear() and ax.clear and they did not work.
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Draw Frame")
self.setGeometry(100,100,680, 450)
# Creation of figure and canvas
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.ax = self.figure.add_subplot(111)
self.ax.axis("off")
#self.toolbar = NavigationToolbar(self.canvas, self)
self.plot_widget = QWidget(self)
self.plot_widget.setGeometry(250, 10, 400, 400)
plot_box = QVBoxLayout()
plot_box.addWidget(self.canvas)
self.plot_widget.setLayout(plot_box)
self.label1=QLabel("Frame height",self)
self.label1.move(10,30)
self.label2 = QLabel("Frame height", self)
self.label2.move(10, 70)
self.lineEdit1=QLineEdit(self)
self.lineEdit1.move(100,30)
self.lineEdit1.setText("10")
self.lineEdit2 = QLineEdit(self)
self.lineEdit2.move(100, 70)
self.lineEdit2.setText("20")
self.button = QPushButton('Draw Frame', self)
self.button.clicked.connect(self.plot)
self.button.move(70, 350)
self.show()
def plot(self):
if len(self.lineEdit1.text())!=0:
self.h=int(self.lineEdit1.text())
else:
self.h=0
if len(self.lineEdit2.text()) != 0:
self.w=int(self.lineEdit2.text())
else:
self.w=0
x = [0, 0, self.w, self.w]
y = [0, self.h, self.h, 0]
self.ax.plot(x, y)
self.canvas.draw()
Picture of the app
Instead of clearing the axes you may update the line that is drawn with the new coordinates.
from PyQt5.QtWidgets import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Draw Frame")
self.setGeometry(100,100,680, 450)
# Creation of figure and canvas
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.ax = self.figure.add_subplot(111)
self.ax.axis("off")
self.line, = self.ax.plot([])
self.ax.axis([0,100,0,100])
#self.toolbar = NavigationToolbar(self.canvas, self)
self.plot_widget = QWidget(self)
self.plot_widget.setGeometry(250, 10, 400, 400)
plot_box = QVBoxLayout()
plot_box.addWidget(self.canvas)
self.plot_widget.setLayout(plot_box)
self.label1=QLabel("Frame height",self)
self.label1.move(10,30)
self.label2 = QLabel("Frame height", self)
self.label2.move(10, 70)
self.lineEdit1=QLineEdit(self)
self.lineEdit1.move(100,30)
self.lineEdit1.setText("10")
self.lineEdit2 = QLineEdit(self)
self.lineEdit2.move(100, 70)
self.lineEdit2.setText("20")
self.button = QPushButton('Draw Frame', self)
self.button.clicked.connect(self.plot)
self.button.move(70, 350)
self.show()
def plot(self):
if len(self.lineEdit1.text())!=0:
self.h=int(self.lineEdit1.text())
else:
self.h=0
if len(self.lineEdit2.text()) != 0:
self.w=int(self.lineEdit2.text())
else:
self.w=0
x = [0, 0, self.w, self.w]
y = [0, self.h, self.h, 0]
self.line.set_data(x,y)
self.canvas.draw()
if __name__=='__main__':
app = QApplication(sys.argv)
w = Window()
app.exec_()
As mentioned in the comment above, you need to call self.ax.clear() every time you click the button. Otherwise you will be redrawing on the same plot. Not sure why your graph doesnt reset on clear(), but here is the code I ran which worked fine. Let me know if it works for you:
from PyQt5.QtWidgets import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Draw Frame")
self.setGeometry(100,100,680, 450)
# Creation of figure and canvas
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.ax = self.figure.add_subplot(111)
self.ax.axis("off")
#self.toolbar = NavigationToolbar(self.canvas, self)
self.plot_widget = QWidget(self)
self.plot_widget.setGeometry(250, 10, 400, 400)
plot_box = QVBoxLayout()
plot_box.addWidget(self.canvas)
self.plot_widget.setLayout(plot_box)
self.label1=QLabel("Frame height",self)
self.label1.move(10,30)
self.label2 = QLabel("Frame height", self)
self.label2.move(10, 70)
self.lineEdit1=QLineEdit(self)
self.lineEdit1.move(100,30)
self.lineEdit1.setText("10")
self.lineEdit2 = QLineEdit(self)
self.lineEdit2.move(100, 70)
self.lineEdit2.setText("20")
self.button = QPushButton('Draw Frame', self)
self.button.clicked.connect(self.plot)
self.button.move(70, 350)
self.show()
def plot(self):
self.ax.clear()
if len(self.lineEdit1.text())!=0:
self.h=int(self.lineEdit1.text())
else:
self.h=0
if len(self.lineEdit2.text()) != 0:
self.w=int(self.lineEdit2.text())
else:
self.w=0
x = [0, 0, self.w, self.w]
y = [0, self.h, self.h, 0]
self.ax.plot(x, y)
self.canvas.draw()
if __name__=='__main__':
app = QApplication(sys.argv)
w = Window()
app.exec_()

Pyqt5. How to clear QVBoxLayout by a Signal?

I try to clear QVBoxLayout with self.vbox.takeAt(0), but previous vboxes clog up the QWidget and would not go away. New appear on top of the old ones.
Whole code https://pastebin.com/n43BH1R0
class Worker(QObject):
CLEAR_VBOX = pyqtSignal()
intReady = pyqtSignal(int)
#pyqtSlot()
def procCounter(self):
for i in range(1, 100):
self.CLEAR_VBOX.emit()
self.intReady.emit(i)
time.sleep(1)
class Form(QWidget):
..
..
def initUI(self):
self.vbox = QVBoxLayout()
self.setLayout(self.vbox)
self.setGeometry(333, 333, 222, 222)
self.show()
def clearvbox(self):
while self.vbox.count():
# ~ # break
self.vbox.takeAt(0)
def onIntReady(self, i):
hbox = QHBoxLayout()
for ii in range(i):
ll = QLabel(str(random.randint(1,9)))
hbox.addWidget(ll)
self.vbox.addLayout(hbox)
def clearvbox(self, L = False):
if not L:
L = self.vbox
if L is not None:
while L.count():
item = L.takeAt(0)
widget = item.widget()
if widget is not None:
widget.deleteLater()
else:
self.clearvbox(item.layout())

How to access from parent method to child object in PyQt5?

I have a button in widget widget which is a central widget of MyApp class, which inherits from QMainWindow. I have connected widget's button to MyApp's method called logic. This is fine, because if I write a method in my main class MyApp(QMainWindow):
def logic(self):
sender = self.sender()
print(sender)
... and click the button I get a message:
PyQt5.QtWidgets.QPushButton object at 0x7ff92e19eaf8
My question is how can I from MyApp's method called logic access to its child object like MyApp.widget.saltLine which is a QLineEdit object? I need to read that line.
class MyApp(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.initui()
def initui(self):
self.setMinimumSize(500, 150)
# create central widget
widget = QWidget()
# lines for entering data
widget.saltLabel = QLabel("Salt:")
widget.hashSunkenLabel = QLabel()
widget.passwordLine = QLineEdit()
widget.resultButton = QPushButton("&Calculate", self)
# set layout
grid = QGridLayout()
grid.addWidget(widget.saltLabel, 0, 0)
grid.addWidget(widget.passwordLine, 1, 0)
grid.addWidget(widget.hashSunkenLabel, 2, 0)
grid.addWidget(widget.resultButton, 2, 1)
# set widget a grid layout and set widget
# as central widget of QMainWindows
widget.setLayout(grid)
self.setCentralWidget(widget)
# don't know how should this look like
widget.resultButton.clicked.connect(self.logic)
def logic(self):
salt = self.saltLine.text()
password = self.passwordLine.text()
resulting_hash = crypt.crypt(password, salt)
self.hashSunkenLabel.setText(resulting_hash)
Or am I definig centralwidget widget wrong? If I do it without a central widget it works fine:
#!/usr/bin/env python3
import sys
import crypt
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QMainWindow, QLabel, QLineEdit, QPushButton,
QWidget, QApplication, QSystemTrayIcon, QFrame, QGridLayout)
class MyApp(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.saltLabel = QLabel("Salt:")
self.saltLine = QLineEdit()
self.saltLine.setPlaceholderText("e.g. $6$xxxxxxxx")
self.passwordLabel = QLabel("Password:")
self.passwordLine = QLineEdit()
self.hashLabel = QLabel("Hash:")
self.hashSunkenLabel = QLabel()
# widget.hashSunkenLabel.setFrameStyle(QFrame.Box | QFrame.Sunken)
self.hashSunkenLabel.setFrameShadow(QFrame.Sunken)
self.resultButton = QPushButton("&Calculate", self)
self.resultButton.setMaximumSize(100, 50)
self.initui()
def initui(self):
# main window size, title and icon
self.setGeometry(300, 300, 500, 150)
self.setWindowTitle("Password hash calculator | Linux")
# set layout
grid = QGridLayout()
grid.addWidget(self.passwordLabel, 0, 0)
grid.addWidget(self.passwordLine, 0, 1)
grid.addWidget(self.saltLabel, 1, 0)
grid.addWidget(self.saltLine, 1, 1)
grid.addWidget(self.resultButton, 2, 1)
grid.addWidget(self.hashLabel, 3, 0)
grid.addWidget(self.hashSunkenLabel, 3, 1)
self.setLayout(grid)
self.resultButton.clicked.connect(self.logic)
def logic(self):
"""
Calculates hash from salt and password
"""
salt = self.saltLine.text()
password = self.passwordLine.text()
resulting_hash = crypt.crypt(password, salt)
self.hashSunkenLabel.setText(resulting_hash)
# sender = self.sender()
# print(sender)
# print(dir(MyApp))
def main():
app = QApplication(sys.argv)
instance = MyApp()
instance.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

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()