Updating QLineEdit on QPushButton click in PyQt5 - python

I currently have the following QLineEdit:
self.lineEdit_15.setText(_translate("Dialog", "email"))
I am trying to update it with the following QPushButton:
self.pushButton_5.setText(_translate("Dialog", "update"))
Ideally, I'd like to get user data and store it as a variable. Any thoughts?

You need to have a look at signals and slots in PyQt.
For example, when a button is clicked it triggers a clicked signal that you can connect to a slot. This slot can do the stuff you need
self.pushButton_5.clicked.connect(self.mySlotFunction)
#Slot that stores lineEdit text in myVar string
def mySlotFunction():
myVar = self.lineEdit_15.text()

Related

pyqt5 - connect a function when QComboBox is clicked [duplicate]

I have been trying to get a QComboBox in PyQt5 to become populated from a database table. The problem is trying to find a method that recognizes a click event on it.
In my GUI, my combo-box is initially empty, but upon clicking on it I wish for the click event to activate my method for communicating to the database and populating the drop-down list. It seems so far that there is no built-in event handler for a click-event for the combo-box. I am hoping that I am wrong on this. I hope someone will be able to tell me that there is a way to do this.
The best article I could find on my use-case here is from this link referring to PyQt4 QComboBox:
dropdown event/callback in combo-box in pyqt4
I also found another link that contains a nice image of a QComboBox.
The first element seems to be a label followed by a list:
Catch mouse button pressed signal from QComboBox popup menu
You can override the showPopup method to achieve this, which will work no matter how the drop-down list is opened (i.e. via the mouse, keyboard, or shortcuts):
from PyQt5 import QtCore, QtWidgets
class ComboBox(QtWidgets.QComboBox):
popupAboutToBeShown = QtCore.pyqtSignal()
def showPopup(self):
self.popupAboutToBeShown.emit()
super(ComboBox, self).showPopup()
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.combo = ComboBox(self)
self.combo.popupAboutToBeShown.connect(self.populateConbo)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.combo)
def populateConbo(self):
if not self.combo.count():
self.combo.addItems('One Two Three Four'.split())
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
However, for your particular use-case, I think a better solution might be to set a QSqlQueryModel on the combo-box, so that the items are updated from the database automatically.
Alternative Solution I :
We can use frame click, the code is to be used in the container of the combo box (windows/dialog/etc.)
def mousePressEvent(self, event):
print("Hello world !")
or
def mousePressEvent():
print("Hello world !")
Alternative Solution II :
We could connect a handler to the pressed signal of the combo's view
self.uiComboBox.view().pressed.connect(self.handleItemPressed)
...
def handleItemPressed(self, index):
item = self.uiComboBox.model().itemFromIndex(index)
print("Do something with the selected item")
Why would you want to populate it when it's activated rather than when the window is loaded?
I am currently developing an application with PySide (another Python binding for the Qt framework), and I populate my comboboxes in the mainwindow class __init__ function, which seems to be the way to go, judging by many examples.
Look at the example code under "QCombobox" over at Zetcode.

When QComboBox is set editable

The code below creates QComboBox and QPushButton both assigned to the same layout. Combobox is set to be editable so the user is able to type a new combobox item's value.
If the user hits Tab keyboard key (instead of Enter) the New Value will not be added to the ComboBox.
Question: How to make sure the ComboBox's items are updated with the New Value even if the user leaves the ComboBox with Tab key?
from PyQt4 import QtGui
def comboActivated(arg=None):
print '\n ...comboActivated: %s'%arg
widget = QtGui.QWidget()
layout = QtGui.QVBoxLayout()
widget.setLayout(layout)
combo = QtGui.QComboBox()
combo.setEditable(True)
combo.addItems(['One','Two','Three'])
combo.activated.connect(comboActivated)
layout.addWidget(combo)
layout.addWidget(QtGui.QPushButton('Push'))
widget.show()
When a user edits the text in the box, the editTextChanged() signal is emitted with the edited text as its argument. In addition, when the widget itself loses focus, as when the user types Tab to move to the button, the widget emits the focusOutEvent() signal. The argument for this signal is a QFocusEvent, which you can query for the reason focus was lost. The reason() method of the event would return Qt.TabFocusReason, for example, if the user hit the Tab button to leave the widget.
You can connect a slot to either (or both) of these signals, so that when the user leaves the widget after editing text, you process it and add it to the box's list of values.
You may also want to look into the QValidator class and its subclasses, which you attach to widgets with editable text, and define the types of valid input for the widget (e.g., integers, text, etc.). This is the best and easiest way to verify a user's input for editable widgets.

QComboBox mouse press event when combo box is initially pressed PyQt4

I'm trying to schedule a mouse press event for a QComboBox. I was wondering if there is any way to schedule a mouse press event on the initial QComboBox click -- the click that brings up the list of items to select. I've already used the currentIndexChanged(int) signal to call a function once the user selects one of the items from the drop down menu, but I'm trying to refresh my QComboBox list with new entries once the user clicks on it. (I have a feeling that this approach may be misguided, but I guess that's another question.)
I've tried making a QComboBox subclass with def mousePressEvent(self, e), but it doesn't seem to do anything. I've also tried def mousePressEvent(self, e) in the QtGui.QWidget class that holds my QComboClass object but, unsurprisingly, that only captures mouse presses for the QtGui.QWidget.
Your current approach is misguided. Even if you could get it working, it would fail whenever the list was opened via the keyboard.
The correct way to do this is to override showPopup:
class ComboBox(QtGui.QComboBox):
def showPopup(self):
self.insertItem(0, 'Added')
super(ComboBox, self).showPopup()

QPushButton tab highlight signal

I'm using PyQt to design an app. For accessibility reasons, I want to speak the name of a button when it is highlighted (using navigation by tab key.)
I have the speech down okay using Windows Speech API. Now I want to use signals and slots, but QPushButton doesn't seem to have a signal for when it is highlighted. The ones I have found are clicked, destroyed, pressed, released, toggled. None of them work.
Is there any way to set up a custom signal that will be emitted when the button is highlighted by tab?
The QApplication is responsible for managing widget focus, so you could connect to its focusChanged signal:
QtGui.qApp.focusChanged.connect(self.handleFocusChanged)
The signal sends references to the previous/current widget that has lost/received the focus (by whatever means), so the handler might look like this:
def handleFocusChanged(self, old, new):
if old is not None and new is not None:
if isinstance(new, QtGui.QPushButton):
print('Button:', new.text())
elif isinstance(new, QtGui.QLineEdit):
print('Line Edit:', new.objectName())
# and so forth...
You can also get the widget that currently has the focus using:
widget = QtGui.qApp.focusWidget()
While the accepted answer by #ekhumoro works, and is the better way (in my opinion), it is also possible to achieve this by subclassing the QPushButton. Something like this:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class FocusButton(QPushButton):
def __init__(self, parent=None):
super(FocusButton, self).__init__(parent)
tabSignal = pyqtSignal()
def focusInEvent(self, QFocusEvent):
self.emit(SIGNAL('tabSignal()'))
It is now possible to create FocusButton objects instead of QPushButton, and they will emit the tabSignal whenever they receive focus.

Big number of pushbuttons and smart checking which is checked

I have dialog:
It contains many flat QPushButtons, QTextEdit and another QPushButton. After click on 'Get list' we can see list of checked buttons in QTextEdit.
My question is how to get this functionality in some smart way. Right now I'm checking every button:
if self.ui.bq6o.isChecked():
cards.append("Q6o")
if self.ui.bk2o.isChecked():
cards.append("K2o")
if self.ui.bq3o.isChecked():
cards.append("Q3o")
if self.ui.bt7s.isChecked():
cards.append("T7s")
if self.ui.bq4o.isChecked():
cards.append("Q4o")
if self.ui.bt4s.isChecked():
cards.append("T4s")
if self.ui.b98o.isChecked():
cards.append("98o")
if self.ui.bjto.isChecked():
cards.append("JTo")
if self.ui.btt.isChecked():
cards.append("TT")
if self.ui.bq7o.isChecked():
cards.append("Q7o")
[...]
Obviously I can't like code like that. I was looking for some widget "button matrix" like, but without luck. I will be grateful for advises.
All the buttons should be children of the same widget, probably the dialog itself. Just get a handle to that widget to get all the child buttons, then loop through them and if they're checked, included their text.
parent = dialog # or whatever
cards = [widget.text() for widget in parent.children() if isinstance(widget, QPushButton) and widget.isChecked()]
You may need to include some code in the if statement to exclude the "Get List" button, or any other pushbuttons in your dialog that could be set to "checked" but shouldn't be included in cards list.
As #Brendan suggested in the other question, you could loop through them in a single list comprehension. But one other approach is to connect each buttons toggled signal to a slot that allows them to register when they are checked.
# somewhere in your class
self.checkedList = set()
def buttonChecked(self, checked):
button = self.sender()
if checked:
self.checkedList.add(button)
else:
if button in self.checkedList:
self.checkedList.remove(button)
# when you create a new button
button.toggled.connect(self.buttonChecked)
This would let you always have a set of just the checked buttons, which are self reporting. Otherwise, you would have to track them under their parent and loop to find out which are checked each time.
Update
Here is a another version that combines #Brendans loop and my signal suggestion. This might help in a situation where your buttons are a bit more spread out across your UI as opposed to be all under a single parent... but first assuming them all under a parent...
parent = dialog
for widget in parent.children():
if isinstance(widget, QPushButton):
widget.toggled.connect(self.buttonChecked)
You could repeat this in your __init__() for all the locations of your buttons and get them all registered to the slot.

Categories