Getting a Blank Progress bar window pyqt 5 - python

I am trying to make work a progress bar with pyqt5 however when I open the Window of the progress bar I am getting a blank windows.
The code for the progress bar generated from the ui is:
Ui_dlg_progress generated from the ui:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_dlg_progress(object):
def setupUi(self, dlg_progress):
dlg_progress.setObjectName("dlg_progress")
dlg_progress.resize(376, 91)
dlg_progress.setSizeGripEnabled(True)
self.gridLayout = QtWidgets.QGridLayout(dlg_progress)
self.gridLayout.setObjectName("gridLayout")
self.label = QtWidgets.QLabel(dlg_progress)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.label_num_folders = QtWidgets.QLabel(dlg_progress)
self.label_num_folders.setObjectName("label_num_folders")
self.gridLayout.addWidget(self.label_num_folders, 0, 1, 1, 1)
self.label_text = QtWidgets.QLabel(dlg_progress)
self.label_text.setObjectName("label_text")
self.gridLayout.addWidget(self.label_text, 0, 2, 1, 1)
self.label_total_folders = QtWidgets.QLabel(dlg_progress)
self.label_total_folders.setObjectName("label_total_folders")
self.gridLayout.addWidget(self.label_total_folders, 0, 3, 1, 1)
self.progressBar = QtWidgets.QProgressBar(dlg_progress)
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName("progressBar")
self.gridLayout.addWidget(self.progressBar, 1, 0, 1, 4)
self.retranslateUi(dlg_progress)
QtCore.QMetaObject.connectSlotsByName(dlg_progress)
def retranslateUi(self, dlg_progress):
_translate = QtCore.QCoreApplication.translate
dlg_progress.setWindowTitle(_translate("dlg_progress", "Processing"))
self.label.setText(_translate("dlg_progress", "Processing:"))
self.label_num_folders.setText(_translate("dlg_progress", "0"))
self.label_text.setText(_translate("dlg_progress", "folders of a total of: "))
self.label_total_folders.setText(_translate("dlg_progress", "1"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
dlg_progress = QtWidgets.QDialog()
ui = Ui_dlg_progress()
ui.setupUi(dlg_progress)
dlg_progress.show()
ProgressBar.py - Calls Ui_dlg_progress
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QDialog
from Ui_progress_bar import Ui_dlg_progress
class dlg_progress(QDialog, Ui_dlg_progress):
"""
Class documentation goes here.
"""
def __init__(self, parent=None):
"""
Constructor
#param parent reference to the parent widget
#type QWidget
"""
super(dlg_progress, self).__init__(parent)
self.setupUi(self)
self.show()
And the main code where is called the progress bar:
def main():
subdirs = [f for f in source.iterdir() if f.is_dir()]
if len(subdirs) == 0:
return -1
prog = dlg_progress()
#Actual number of folders procecessed
proc_folders = 0
prog.progressBar.setValue(proc_folders)
prog.label_num_folders.setText(str(proc_folders))
prog.label_total_folders.setText(str(len(subdirs)))
prog.progressBar.maximum = len(subdirs)
for subdir in subdirs:
process of the folders
#Number of processed folders
proc_folders += 1
prog.setValue(proc_folders)
prog.label_num_folders.setText(str(proc_folders))
QApplication.processEvents()
return 0

It just looks like a typo in the last loop :
for subdir in subdirs:
#Number of processed folders
proc_folders += 1
prog.progressBar.setValue(proc_folders)
prog.label_num_folders.setText(str(proc_folders))
QApplication.processEvents()
Otherwise, you should test the source and the length of generated list, if it's empty, the loop won't start, and the progressbar will stay at 0.

Related

I can't close completely PyQt5 script

When I run the following script, named test2.py, if I click on Ok or Cancel button the window closes but I don't get the prompt. I think I forgot something stupid ...
This is the test2.py script:
from PyQt5 import Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
import sys
import unittest
class MainAppWindow(QMainWindow):
def __init__(self):
super().__init__()
dialog = Qt.QDialog()
buttonbox = Qt.QDialogButtonBox(Qt.QDialogButtonBox.Ok | Qt.QDialogButtonBox.Cancel)
layout = Qt.QVBoxLayout()
param_box = Qt.QGroupBox('Iterate over parameters:')
pblayout = Qt.QVBoxLayout()
pblayout.setContentsMargins(0, 0, 0, 0)
scroll = Qt.QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameStyle(scroll.NoFrame)
scroll.setViewportMargins(0, 0, 0, 0)
pblayout.addWidget(scroll)
param_lay = Qt.QGridLayout()
wid = Qt.QWidget()
scroll.setWidget(wid)
wid.setLayout(param_lay)
param_box.setLayout(pblayout)
layout.addWidget(param_box)
layout.addWidget(buttonbox)
dialog.setLayout(layout)
buttonbox.accepted.connect(dialog.accept)
buttonbox.rejected.connect(dialog.reject)
param_lay.addWidget(Qt.QLabel('iter. / database:'), 0, 0, 1, 3)
param_lay.addWidget(Qt.QLabel('iter.:'), 0, 3, 1, 2)
param_lay.setColumnStretch(2, 1)
param_lay.setColumnStretch(4, 1)
param_lay.setRowStretch(0, 0)
res = dialog.exec_()
if res != dialog.Accepted:
print('dialog not accepted')
else:
print('dialog accepted')
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MainAppWindow()
sys.exit(app.exec_())
When I run the script with python3 test2.py, I observe in stdout the dialog accepted or dialog not accepted depending on the button clicked, the window closes but I don't get the prompt. I have to stop manually (CtrLZ) to get the prompt.
The problem is that you have 2 eventloops: dialog.exec_() and app.exec_() so when the first eventloop finishes the other eventloop starts. On the other hand, it is useless to create a class that inherits from MainAppWindow since the window is never used or shown.
One possible solution is to start only one eventloop:
import sys
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QDialogButtonBox,
QGridLayout,
QGroupBox,
QLabel,
QMainWindow,
QScrollArea,
QVBoxLayout,
QWidget,
)
def main():
dialog = QDialog()
buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
layout = QVBoxLayout(dialog)
param_box = QGroupBox("Iterate over parameters:")
pblayout = QVBoxLayout()
pblayout.setContentsMargins(0, 0, 0, 0)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setFrameStyle(scroll.NoFrame)
scroll.setViewportMargins(0, 0, 0, 0)
pblayout.addWidget(scroll)
param_lay = QGridLayout()
wid = QWidget()
scroll.setWidget(wid)
wid.setLayout(param_lay)
param_box.setLayout(pblayout)
layout.addWidget(param_box)
layout.addWidget(buttonbox)
buttonbox.accepted.connect(dialog.accept)
buttonbox.rejected.connect(dialog.reject)
param_lay.addWidget(QLabel("iter. / database:"), 0, 0, 1, 3)
param_lay.addWidget(QLabel("iter.:"), 0, 3, 1, 2)
param_lay.setColumnStretch(2, 1)
param_lay.setColumnStretch(4, 1)
param_lay.setRowStretch(0, 0)
res = dialog.exec_()
if res != dialog.Accepted:
print("dialog not accepted")
else:
print("dialog accepted")
if __name__ == "__main__":
app = QApplication(sys.argv)
main()

How to iterate over elements of a list one at a time using a pushButton

I have a list of strings that i want to print the next element of the it by pressing a pushbutton each time.
Also, how can i print the previous item of the list by pressing another pushbutton?
Here is a sample code:
from PyQt5 import QtCore, QtWidgets
import sys
class Main(QtWidgets.QMainWindow):
def __init__(self):
self.pushbutton = QtWidgets.QPushButton(self)
self.pushbutton.move(20,20)
self.list = ["first","second","third"]
self.setGeometry(300,300,250,180)
self.pushbutton.clicked.connect(self.showElements)
self.show()
def showElements(self):
pass
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Try it:
import sys
from PyQt5 import QtCore, QtWidgets
class Example(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.centralWidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralWidget)
self.list = ["first", "second", "third"]
self.len_list = len(self.list) - 1
self.index = 0
self.label = QtWidgets.QLabel(self.list[self.index])
button1 = QtWidgets.QPushButton('next')
button1.clicked.connect(self.search_next)
button2 = QtWidgets.QPushButton('previous')
button2.clicked.connect(self.search_previous)
layout = QtWidgets.QGridLayout(self.centralWidget)
layout.addWidget(self.label, 0, 0, 1, 2, alignment=QtCore.Qt.AlignHCenter)
layout.addWidget(button2, 1, 0)
layout.addWidget(button1, 1, 1)
def search_next(self):
if self.index >= self.len_list:
self.index = 0
else:
self.index += 1
self.label.setText(self.list[self.index])
def search_previous(self):
if self.index <= 0:
self.index = self.len_list
else:
self.index -= 1
self.label.setText(self.list[self.index])
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
You can use generators to have the functionality you asked
For example:
a = [1,2,3]
def myFunction():
for item in a:
yield item
# Get iterator
iterator = myFunction()
# Call this on every button push
nextItem = next(iterator)
print(nextItem)
Here's a working repl.it project:
https://repl.it/#HarunYlmaz/generators-iterators

How to check if a RadioButton was checked from another class?

I'm making a GUI in PyQt5 where there are multiple tabs. In one of the tabs, users select a radio button with what type of data they are entering.
This information changes what buttons are available in other tabs and I'm having trouble getting this information passed from the original tab class. I'd like to see if a radio button is checked from another tab and if it is, enable a button.
I have a function to return a string depending on which radio button is selected, but when I call the getDataType() function from the other tab, I get the error "AttributeError: module 'DataTab' has no attribute 'getDataType.'"
I've tried moving the getDataType() function outside of the DataTab class, but since the radio buttons use "self," I'm not able to access them.
I've also tried making a new class and calling that new class from the function, but then I get stuck on how to get the information to my other tab.
So in this example, once a user selects a radio button in the Data Tab, I want the corresponding push button on the Analysis Tab enabled.
When I uncomment the call to getDataType(), I get the following error: "AttributeError: module 'DataTab' has no attribute 'getDataType'"
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QLabel, QTableWidget, QTableWidgetItem,
QLineEdit, QFileDialog, QRadioButton, QGroupBox, QPushButton,
QGridLayout, QButtonGroup, QApplication, QAbstractItemView,
QTabWidget)
from PyQt5.QtGui import QIcon
import sys, os
class TabPage(QTabWidget):
def __init__(self):
super().__init__()
self.setStyleSheet('font: 15pt Tw Cen MT')
self.show()
# Creating the tabs here to have a reference
self.tabWidget = QTabWidget()
self.tabWidget.addTab(DataTab(), "Data Input")
self.tabWidget.addTab(AnalysisTab(), "Analysis")
self.layout = QVBoxLayout()
self.layout.addWidget(self.tabWidget)
self.setLayout(self.layout)
# The DataTab class holds all the GUI for the DataTab
class DataTab(QWidget):
def __init__(self):
super().__init__()
self.app = QApplication(sys.argv)
self.layout = QGridLayout()
self.intervalRadioButton = QRadioButton("Interval")
self.ordinalRadioButton = QRadioButton("Ordinal")
self.frequencyRadioButton = QRadioButton("Frequency")
self.submitButton = QPushButton("Submit Data")
self.layout.addWidget(self.intervalRadioButton, 7, 0, 1, 3)
self.layout.addWidget(self.ordinalRadioButton, 8, 0, 1, 3)
self.layout.addWidget(self.frequencyRadioButton, 9, 0, 1, 3)
self.setLayout(self.layout)
self.show()
def getDataType(self):
if self.intervalRadioButton.isChecked():
return "interval"
elif self.ordinalRadioButton.isChecked():
return "ordinal"
elif self.frequencyRadioButton.isChecked():
return "frequency"
class AnalysisTab(QWidget):
def __init__(self):
super().__init__()
self.app = QApplication(sys.argv)
self.createChooseIntervalGroup()
self.createChooseOrdinalGroup()
self.createChooseFrequencyGroup()
self.layout = QGridLayout()
self.layout.addWidget(self.ChooseIntervalGroup, 0, 1)
self.layout.addWidget(self.ChooseOrdinalGroup, 1, 1)
self.layout.addWidget(self.ChooseFrequencyGroup, 2, 1)
self.setLayout(self.layout)
self.show()
# The right side of AnalysisTab containing the buttons for
# analysis
def createChooseIntervalGroup(self):
self.ChooseIntervalGroup = QGroupBox("Tests for Interval Data")
self.analyzeIntervalButton = QPushButton("Analyze")
self.analyzeIntervalButton.setEnabled(False)
# if DataTab.getDataType() != "interval":
# self.analyzeIntervalButton.setEnabled(True)
self.layout = QGridLayout()
self.layout.addWidget(self.analyzeIntervalButton, 1, 1)
self.ChooseIntervalGroup.setLayout(self.layout)
# The right side of AnalysisTab containing the buttons for
# analysis
def createChooseOrdinalGroup(self):
self.ChooseOrdinalGroup = QGroupBox("Tests for Ordinal Data")
self.analyzeOrdinalButton = QPushButton("Analyze")
self.analyzeOrdinalButton.setEnabled(False)
# if DataTab.getDataType() != "ordinal":
# self.analyzeIntervalButton.setEnabled(True)
self.layout = QGridLayout()
self.layout.addWidget(self.analyzeOrdinalButton, 1, 1)
self.ChooseOrdinalGroup.setLayout(self.layout)
# The right side of AnalysisTab containing the buttons for
# analysis
def createChooseFrequencyGroup(self):
self.ChooseFrequencyGroup = QGroupBox("Tests for Frequency Data")
self.analyzeFrequencyButton = QPushButton("Analyze")
self.analyzeFrequencyButton.setEnabled(False)
# if DataTab.getDataType() != "frequency":
# self.analyzeIntervalButton.setEnabled(True)
self.layout = QGridLayout()
self.layout.addWidget(self.analyzeFrequencyButton, 1, 1)
self.ChooseFrequencyGroup.setLayout(self.layout)
def run():
app = QApplication(sys.argv)
tabPage = TabPage()
tabPage.show()
app.exec_()
run()
A possible solution for this case is to use the signals to notify the change of status of the QRadioButton to enable or disable the button.
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
QWidget,
QVBoxLayout,
QRadioButton,
QGroupBox,
QPushButton,
QGridLayout,
QButtonGroup,
QApplication,
QTabWidget,
)
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet("font: 15pt Tw Cen MT")
self.data_tab = DataTab()
self.analysis_tab = AnalysisTab()
self.tabWidget = QTabWidget()
self.tabWidget.addTab(self.data_tab, "Data Input")
self.tabWidget.addTab(self.analysis_tab, "Analysis")
layout = QVBoxLayout(self)
layout.addWidget(self.tabWidget)
self.data_tab.intervalRadioButton.toggled.connect(
self.analysis_tab.analyzeIntervalButton.setEnabled
)
self.data_tab.ordinalRadioButton.toggled.connect(
self.analysis_tab.analyzeOrdinalButton.setEnabled
)
self.data_tab.frequencyRadioButton.toggled.connect(
self.analysis_tab.analyzeFrequencyButton.setEnabled
)
class DataTab(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QGridLayout(self)
self.intervalRadioButton = QRadioButton("Interval")
self.ordinalRadioButton = QRadioButton("Ordinal")
self.frequencyRadioButton = QRadioButton("Frequency")
self.submitButton = QPushButton("Submit Data")
layout.addWidget(self.intervalRadioButton, 7, 0, 1, 3)
layout.addWidget(self.ordinalRadioButton, 8, 0, 1, 3)
layout.addWidget(self.frequencyRadioButton, 9, 0, 1, 3)
class AnalysisTab(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.createChooseIntervalGroup()
self.createChooseOrdinalGroup()
self.createChooseFrequencyGroup()
layout = QGridLayout(self)
layout.addWidget(self.ChooseIntervalGroup, 0, 1)
layout.addWidget(self.ChooseOrdinalGroup, 1, 1)
layout.addWidget(self.ChooseFrequencyGroup, 2, 1)
def createChooseIntervalGroup(self):
self.ChooseIntervalGroup = QGroupBox("Tests for Interval Data")
self.analyzeIntervalButton = QPushButton("Analyze")
self.analyzeIntervalButton.setEnabled(False)
layout = QGridLayout(self.ChooseIntervalGroup)
layout.addWidget(self.analyzeIntervalButton, 1, 1)
def createChooseOrdinalGroup(self):
self.ChooseOrdinalGroup = QGroupBox("Tests for Ordinal Data")
self.analyzeOrdinalButton = QPushButton("Analyze")
self.analyzeOrdinalButton.setEnabled(False)
layout = QGridLayout(self.ChooseOrdinalGroup)
layout.addWidget(self.analyzeOrdinalButton, 1, 1)
def createChooseFrequencyGroup(self):
self.ChooseFrequencyGroup = QGroupBox("Tests for Frequency Data")
self.analyzeFrequencyButton = QPushButton("Analyze")
self.analyzeFrequencyButton.setEnabled(False)
layout = QGridLayout(self.ChooseFrequencyGroup)
layout.addWidget(self.analyzeFrequencyButton, 1, 1)
def run():
app = QApplication(sys.argv)
tabPage = Widget()
tabPage.show()
app.exec_()
run()

QGridLayout Widgets Overlapping

I am trying to create a program where the user has three options to answer a question. I used QGridLayout for this but only the last widget added to the QGridLayout is shown.
Expected:
################################
# Text #
################################
########## ########## ##########
#Button 1# #Button 2# #Button 3#
########## ########## ##########
Reality:
##########
#Button 3#
##########
Simplified Python 3 Code (No Text Widget):
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
QApp = QApplication(sys.argv)
QMWRoot = QMainWindow()
QGLRoot = QGridLayout(QMWRoot)
QMWRoot.setLayout(QGLRoot)
QPB0 = QPushButton('B0x0', QMWRoot)
QGLRoot.addWidget(QPB0, 0, 0)
QPB1 = QPushButton('B0x1', QMWRoot)
QGLRoot.addWidget(QPB1, 0, 1)
QPB2 = QPushButton('B1x0', QMWRoot)
QGLRoot.addWidget(QPB2, 1, 0)
QMWRoot.show()
sys.exit(QApp.exec_())
Original (Unfinished) Python 3 Code:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class Root(QMainWindow):
def __init__(self, QApp):
super().__init__()
self.QApp = QApp
def setupUi(self):
self.setWindowTitle('')
self.QGLRoot = QGridLayout()
self.setLayout(self.QGLRoot)
self.QLBTool = QLabel()
self.QLBTool.setText('Tool')
self.QGLRoot.addWidget(self.QLBTool, 0, 0)
self.QPB0 = QPushButton(self)
self.QPB0.setText('0')
self.QGLRoot.addWidget(self.QPB0, 1, 0)
self.QPB1 = QPushButton(self)
self.QPB1.setText('1')
self.QGLRoot.addWidget(self.QPB1, 1, 1)
self.QPB2 = QPushButton(self)
self.QPB2.setText('2')
self.QGLRoot.addWidget(self.QPB2, 1, 2)
def startUi(self):
self.show()
def updateUi(self):
pass
QApp = QApplication(sys.argv)
App = Root(QApp)
App.setupUi()
App.startUi()
sys.exit(QApp.exec_())
QMainWindow you have a special structure:
So in your case you must establish a centralwidget and there place the layout.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Root(QMainWindow):
def __init__(self, QApp):
super().__init__()
self.QApp = QApp
def setupUi(self):
self.setWindowTitle('')
widget = QWidget()
self.setCentralWidget(widget)
self.QGLRoot = QGridLayout()
widget.setLayout(self.QGLRoot)
self.QLBTool = QLabel()
self.QLBTool.setAlignment(Qt.AlignHCenter)
self.QLBTool.setText('Tool')
self.QGLRoot.addWidget(self.QLBTool, 0, 0, 1, 3)
self.QPB0 = QPushButton()
self.QPB0.setText('0')
self.QGLRoot.addWidget(self.QPB0, 1, 0)
self.QPB1 = QPushButton()
self.QPB1.setText('1')
self.QGLRoot.addWidget(self.QPB1, 1, 1)
self.QPB2 = QPushButton()
self.QPB2.setText('2')
self.QGLRoot.addWidget(self.QPB2, 1, 2)
def startUi(self):
self.show()
QApp = QApplication(sys.argv)
App = Root(QApp)
App.setupUi()
App.startUi()
sys.exit(QApp.exec_())
Compact and generalized code:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, \
QGridLayout, QLabel, QPushButton
class Root(QMainWindow):
def __init__(self, QApp):
super().__init__()
self.setupUi()
def setupUi(self):
self.setWindowTitle('')
widget = QWidget()
self.setCentralWidget(widget)
QGLRoot = QGridLayout(widget)
options = ("0", "1", "2")
QLBTool = QLabel('Tool')
QLBTool.setAlignment(Qt.AlignHCenter)
QGLRoot.addWidget(QLBTool, 0, 0, 1, len(options))
for i, option in enumerate(options):
button = QPushButton(option)
QGLRoot.addWidget(button, 1, i)
QApp = QApplication(sys.argv)
App = Root(QApp)
App.show()
sys.exit(QApp.exec_())

Clear QLineEdit on click event

I am using the given code, I want the user to enter text in the QLineEdit widget, press the Copy! button and see the inputted text replace the 'N/A' label. My questions is: following this procedure, how can I clear the text inputted in the QLineEdit widget with a simple mouse click?
From what I read (this, this and this) it seems like I need to reimplement focusInEvent() in a new class extending QLineEdit. My problem is that the code for my GUI has been imported from Qt Designer using pyuic5 and the examples cited above don't seem to take this in consideration.
Here is my code:
from PyQt5.QtWidgets import *
import sys
import QLineEdit_test
class MainWindow(QMainWindow, QLineEdit_test.Ui_QLineEdit_test):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.copy_button.clicked.connect(self.copy_and_print)
def copy_and_print(self):
self.label.setText(self.lineEdit.text())
def main():
app = QApplication(sys.argv)
form = MainWindow()
form.show()
app.exec_()
if __name__ == "__main__":
main()
Here is my converted .ui file:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_QLineEdit_test(object):
def setupUi(self, QLineEdit_test):
QLineEdit_test.setObjectName("QLineEdit_test")
QLineEdit_test.resize(300, 200)
QLineEdit_test.setMaximumSize(QtCore.QSize(300, 200))
self.centralwidget = QtWidgets.QWidget(QLineEdit_test)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setMaximumSize(QtCore.QSize(120, 16777215))
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 1)
self.copy_button = QtWidgets.QPushButton(self.centralwidget)
self.copy_button.setObjectName("copy_button")
self.gridLayout.addWidget(self.copy_button, 1, 0, 1, 1)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setMaximumSize(QtCore.QSize(200, 20))
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
QLineEdit_test.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(QLineEdit_test)
self.menubar.setGeometry(QtCore.QRect(0, 0, 300, 22))
self.menubar.setObjectName("menubar")
QLineEdit_test.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(QLineEdit_test)
self.statusbar.setObjectName("statusbar")
QLineEdit_test.setStatusBar(self.statusbar)
self.retranslateUi(QLineEdit_test)
QtCore.QMetaObject.connectSlotsByName(QLineEdit_test)
def retranslateUi(self, QLineEdit_test):
_translate = QtCore.QCoreApplication.translate
QLineEdit_test.setWindowTitle(_translate("QLineEdit_test", "MainWindow"))
self.copy_button.setText(_translate("QLineEdit_test", "Copy!"))
self.copy_button.setShortcut(_translate("QLineEdit_test", "Return"))
self.label.setText(_translate("QLineEdit_test", "N/A"))
The solution is to promote QtDesigner use our custom QLineEdit where we implement the signal clicked with the help of mousePressEvent, this class will be called ClickableLineEdit and the file will be called ClickableLineEdit.py.
ClickableLineEdit.py
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QLineEdit
class ClickableLineEdit(QLineEdit):
clicked = pyqtSignal()
def mousePressEvent(self, event):
self.clicked.emit()
QLineEdit.mousePressEvent(self, event)
To promote it, the following structure will be considered:
.
├── ClickableLineEdit.py
├── main.py
├── your.ui
└── QLineEdit_test.py
Open the design with Qt Designer and right click on the QLineEdit and select Promote to ...:
A menu will open and place the following
then press and Promote. Then we generate the code again.
Then we connect the signal to clear:
class MainWindow(QMainWindow, QLineEdit_test.Ui_QLineEdit_test):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.copy_button.clicked.connect(self.copy_and_print)
self.lineEdit.clicked.connect(self.lineEdit.clear)
def copy_and_print(self):
self.label.setText(self.lineEdit.text())
Update:
PySide2:
from PySide2 import QtCore, QtWidgets
class ClickableLineEdit(QtWidgets.QLineEdit):
clicked = QtCore.Signal()
def mousePressEvent(self, event):
super(ClickableLineEdit, self).mousePressEvent(event)
self.clicked.emit()
class App(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.lineedit = ClickableLineEdit()
self.lineedit.clicked.connect(self.lineedit.clear)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.lineedit)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
layout = QGridLayout()
self.setLayout(layout)
self.lineedit = QLineEdit()
self.lineedit.returnPressed.connect(self.press)
layout.addWidget(self.lineedit, 0, 0)
def press(self):
print("Hi World")
self.lineedit.clear()
If someone is still looking for a way to do this, but you only want the Line edit to be cleared when it first clicked and not every time it is clicked, you can do so without using variables like this :
def init_UI(self):
self.text_input = QLineEdit('Type your name')
self.text_input.mousePressEvent = self._mousePressEvent
def _mousePressEvent(self, event):
self.text_input.clear()
self.text_input.mousePressEvent = None
This way the _mousePressEvent gets called only once
I have an optional solution in one line:
self.lineEdit.mouseReleaseEvent = self.copy_and_print
Make sure you are receiving two parameters in your function (self,event)
I hope I helped you
Full post: https://wiki.python.org/moin/PyQt/Making%20non-clickable%20widgets%20clickable
Use mousePressEvent of QLineEdit to detect mouse click. To clear the text use clear() method or setText() method of QLineEdit.
#called when ever mouse is pressed
def mousePressed(self, event):
print('mouse pressed')
self.lineEdit=QLineEdit("Awesome day")#from PyQt5.QtWidget import QLineEdit
self.lineEdit.mousePressEvent = self.mousePressed
Example program :
import sys
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QApplication, QLineEdit
class ButtonPanel(QWidget):
def __init__(self, heading):
self.initUI(heading)
def initUI(self, heading):
super().__init__()
self.layout = QHBoxLayout()
self.lineEdit = QLineEdit(heading)
#self.lineEdit.setReadOnly(True)
self.lineEdit.returnPressed.connect(self.returnPressed)
self.lineEdit.mousePressEvent = self.mousePressed
self.delete = QPushButton("D")
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.delete)
self.setLayout(self.layout)
self.show()
#called when mouse is clicked
def mousePressed(self, event):
self.lineEdit.clear() #text is cleared
//self.lineEdit.setText("") #this way we can also clear the text
print('mouse pressed')
//called when return key is pressed
def returnPressed(self):
print('return pressed')
if __name__ == "__main__":
app = QApplication(sys.argv)
b = ButtonPanel("Awesome")
sys.exit(app.exec())
Output :

Categories

Resources