A possible solution is to create a custom QComboBox:
import sys
from PyQt5 import QtCore, QtWidgets
class ComboBox(QtWidgets.QComboBox):
new_signal = QtCore.pyqtSignal(str, str)
def __init__(self, parent=None):
super(ComboBox, self).__init__(parent)
self.lastSelected = ""
self.activated[str].connect(self.onActivated)
def onActivated(self, text):
self.new_signal.emit(self.lastSelected, text)
self.lastSelected = text
class BaseWidget(QtWidgets.QWidget):
def __init__(self):
super(BaseWidget, self).__init__()
self.setGeometry(300, 300, 300, 200)
# 2 Labels to display the new and the old item after selection
self.LabelOldItem = QtWidgets.QLabel()
self.LabelNewItem = QtWidgets.QLabel()
self.MyCombobox = ComboBox()
self.MyCombobox.addItems(['Item 1', 'Item 2', 'Item 3', 'Item 4'])
self.MyCombobox.new_signal.connect(self.ComboChange)
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.MyCombobox, 0, 0, 1, 1)
grid.addWidget(self.LabelOldItem, 1, 0, 1, 1)
grid.addWidget(self.LabelNewItem, 2, 0, 1, 1)
def ComboChange(self, lastitem, newitem):
self.LabelOldItem.setText('Previous Selection: <b>{}</b>'.format(lastitem))
self.LabelNewItem.setText('New Selection: <b>{}</b>'.format(newitem))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
pyqtComboExample = BaseWidget()
pyqtComboExample.show()
sys.exit(app.exec_())
Another possible solution is to use sender()
to get the QComboBox used, and save the old item in a property:
import sys
from PyQt5 import QtCore, QtWidgets
class BaseWidget(QtWidgets.QWidget):
def __init__(self):
super(BaseWidget, self).__init__()
self.setGeometry(300, 300, 300, 200)
# 2 Labels to display the new and the old item after selection
self.LabelOldItem = QtWidgets.QLabel()
self.LabelNewItem = QtWidgets.QLabel()
self.MyCombobox = QtWidgets.QComboBox()
self.MyCombobox.addItems(['Item 1', 'Item 2', 'Item 3', 'Item 4'])
self.MyCombobox.activated[str].connect(self.ComboChange)
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.MyCombobox, 0, 0, 1, 1)
grid.addWidget(self.LabelOldItem, 1, 0, 1, 1)
grid.addWidget(self.LabelNewItem, 2, 0, 1, 1)
def ComboChange(self, newitem):
combo = self.sender()
lastitem = combo.property("lastitem")
self.LabelOldItem.setText('Previous Selection: <b>{}</b>'.format(lastitem))
self.LabelNewItem.setText('New Selection: <b>{}</b>'.format(newitem))
combo.setProperty("lastitem", newitem)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
pyqtComboExample = BaseWidget()
pyqtComboExample.show()
sys.exit(app.exec_())
Whenever the combo selection changes, I'm simply clearing the QLineEdit which I don't want.,For example, when an integer type is selected from the QComboBox then I will not let the user type regular text in the QLineEdit object and vice versa.,Hi, My QComboBox along with QLineEdit contains different datatypes (3 fields of int and 3 fields of string) and I'm already doing some validation based on what the user selects as type. For example, when an integer type is selected from the QComboBox then I will not let the user type regular text in the QLineEdit object and vice versa.,To clear out, or not clear out, the QLineEdit depending on the newly selected combo index you will want something like:
Whenever the combo selection changes, I'm simply clearing the QLineEdit which I don't want.
_typeBox = new QComboBox(this);
_typeBox->insertItem(static_cast<int>(ItemType::e_CID), tr("Cellphone ID"));
_typeBox->insertItem(static_cast<int>(ItemType::e_EID), tr("Emergeny ID"));
_typeBox->insertItem(static_cast<int>(ItemType::e_FName), tr("First Name"));
_typeBox->insertItem(static_cast<int>(ItemType::e_LName), tr("Last Name"));
_typeBox->insertItem(static_cast<int>(ItemType::e_PName), tr("Property Name"));
_typeBox->insertItem(static_cast<int>(ItemType::e_PValue), tr("Property Value"));
connect(_typeBox, SIGNAL(activated(int)), this, SLOT(typeIndexChanged(int)));
void typeIndexChanged(int index) {
_lineEdit->clear();
}
if i dont misunderstood your question , I would define a variable that holds the previous index information.
private:
int _lastIndex = 0
//--------
void typeIndexChanged(int index) {
if (_lastIndex == 0) {
_lastIndex = index;
} else if (index != _lastIndex) {
_lineEdit - > clear();
_lastIndex = index;
}
}
To clear out, or not clear out, the QLineEdit
depending on the newly selected combo index you will want something like:
void typeIndexChanged(int index)
{
// `index` must be the *new* current index
if (!lineEditContentIsValidForComboIndex(static_cast<ItemType>(index)))
_lineEdit->clear();
}
bool lineEditContentIsValidForComboIndex(ItemType itemType)
{
switch (itemType)
{
case ItemType::e_CID:
case ItemType::e_EID:
case ItemType::e_PValue:
return textIsNumber(_lineEdit->text());
case ItemType::e_FName:
case ItemType::e_LName:
return textIsLetters(_lineEdit->text());
case ItemType::e_PName:
default:
return true;
}
}
In my program some comboboxes (QComboBox) were used to make several settings. Sometimes its necessary not only to know the item the user selected but also the item which was selected previously in the combobox. Well, transferring the new selection is quite easy:,My compromise solution would be to manually set a variable for every combobox which stores the last selected value so that it can be accessed when the selction has changed. But considering that i have a lot of Comboboxes this would be quite prone to errors until some boxes could be updated on different ways.,Another possible solution is to use sender() to get the QComboBox used, and save the old item in a property:,But how do i manage to not only passing the newly selected but also the previous item to a function when the index changed?
In my program some comboboxes (QComboBox) were used to make several settings. Sometimes its necessary not only to know the item the user selected but also the item which was selected previously in the combobox. Well, transferring the new selection is quite easy:
self.MyCombobox.activated[str].connect(self.ComboChange)
A minimal working example:
import sys
from PyQt5.QtWidgets import ( QApplication, QWidget, QGridLayout, QComboBox,
QLabel)
class BaseWidget(QWidget):
def __init__(self):
super(BaseWidget, self).__init__()
self.setGeometry(300, 300, 300, 200)
# 2 Labels to display the new and the old item after selection
self.LabelOldItem = QLabel(self)
self.LabelNewItem = QLabel(self)
self.MyCombobox = QComboBox(self)
self.MyCombobox.addItems(['Item 1', 'Item 2', 'Item 3', 'Item 4'])
self.MyCombobox.activated[str].connect(self.ComboChange)
grid = QGridLayout()
grid.addWidget(self.MyCombobox, 0, 0, 1, 1)
grid.addWidget(self.LabelOldItem, 1, 0, 1, 1)
grid.addWidget(self.LabelNewItem, 2, 0, 1, 1)
self.setLayout(grid)
def ComboChange(self, newitem):
self.LabelOldItem.setText('Previous Selection: ') # <- crucial point # How can i transfer both, not only the new item but also the previous # item of the combobox when it gets activated? self.LabelNewItem.setText('New Selection: <b>' + newitem + '</b>')
if __name__ == '__main__':
app = QApplication(sys.argv)
pyqtComboExample = BaseWidget()
pyqtComboExample.show()
sys.exit(app.exec_())
A possible solution is to create a custom QComboBox:
import sys
from PyQt5 import QtCore, QtWidgets
class ComboBox(QtWidgets.QComboBox):
new_signal = QtCore.pyqtSignal(str, str)
def __init__(self, parent=None):
super(ComboBox, self).__init__(parent)
self.lastSelected = ""
self.activated[str].connect(self.onActivated)
def onActivated(self, text):
self.new_signal.emit(self.lastSelected, text)
self.lastSelected = text
class BaseWidget(QtWidgets.QWidget):
def __init__(self):
super(BaseWidget, self).__init__()
self.setGeometry(300, 300, 300, 200)
# 2 Labels to display the new and the old item after selection
self.LabelOldItem = QtWidgets.QLabel()
self.LabelNewItem = QtWidgets.QLabel()
self.MyCombobox = ComboBox()
self.MyCombobox.addItems(['Item 1', 'Item 2', 'Item 3', 'Item 4'])
self.MyCombobox.new_signal.connect(self.ComboChange)
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.MyCombobox, 0, 0, 1, 1)
grid.addWidget(self.LabelOldItem, 1, 0, 1, 1)
grid.addWidget(self.LabelNewItem, 2, 0, 1, 1)
def ComboChange(self, lastitem, newitem):
self.LabelOldItem.setText('Previous Selection: <b>{}</b>'.format(lastitem))
self.LabelNewItem.setText('New Selection: <b>{}</b>'.format(newitem))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
pyqtComboExample = BaseWidget()
pyqtComboExample.show()
sys.exit(app.exec_())
Another possible solution is to use sender()
to get the QComboBox used, and save the old item in a property:
import sys
from PyQt5 import QtCore, QtWidgets
class BaseWidget(QtWidgets.QWidget):
def __init__(self):
super(BaseWidget, self).__init__()
self.setGeometry(300, 300, 300, 200)
# 2 Labels to display the new and the old item after selection
self.LabelOldItem = QtWidgets.QLabel()
self.LabelNewItem = QtWidgets.QLabel()
self.MyCombobox = QtWidgets.QComboBox()
self.MyCombobox.addItems(['Item 1', 'Item 2', 'Item 3', 'Item 4'])
self.MyCombobox.activated[str].connect(self.ComboChange)
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.MyCombobox, 0, 0, 1, 1)
grid.addWidget(self.LabelOldItem, 1, 0, 1, 1)
grid.addWidget(self.LabelNewItem, 2, 0, 1, 1)
def ComboChange(self, newitem):
combo = self.sender()
lastitem = combo.property("lastitem")
self.LabelOldItem.setText('Previous Selection: <b>{}</b>'.format(lastitem))
self.LabelNewItem.setText('New Selection: <b>{}</b>'.format(newitem))
combo.setProperty("lastitem", newitem)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
pyqtComboExample = BaseWidget()
pyqtComboExample.show()
sys.exit(app.exec_())
last modified July 9, 2020
#!/usr/bin/python
import sys
from PyQt5.QtWidgets import(QWidget, QLabel, QHBoxLayout,
QComboBox, QApplication)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
self.lbl = QLabel('Ubuntu', self)
combo = QComboBox(self)
combo.addItem('Ubuntu')
combo.addItem('Xubuntu')
combo.addItem('Fedora')
combo.addItem('Arch')
combo.addItem('Gentoo')
combo.activated[str].connect(self.onActivated)
hbox.addWidget(combo)
hbox.setSpacing(20)
hbox.addWidget(self.lbl)
self.setContentsMargins(20, 20, 20, 20)
self.setLayout(hbox)
self.move(300, 300)
self.setWindowTitle('QComboBox')
self.show()
def onActivated(self, text):
self.lbl.setText(text)
self.lbl.adjustSize()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
We have a combobox and a label. The selected item is displayed in the label.
combo = QComboBox(self)
combo.addItem('Ubuntu')
combo.addItem('Xubuntu')
...
A new item is added with addItem
combo.activated[str].connect(self.onActivated)
#!/usr/bin/python
import sys
from PyQt5.QtWidgets import(QWidget, QHBoxLayout,
QComboBox, QApplication)
from PyQt5.QtGui
import QIcon
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
combo = QComboBox(self)
combo.addItem('Disk')
combo.setItemIcon(0, QIcon('disk.png'))
combo.addItem('Web')
combo.setItemIcon(1, QIcon('web.png'))
combo.addItem('Computer')
combo.setItemIcon(2, QIcon('computer.png'))
hbox.addWidget(combo)
hbox.setSpacing(20)
self.setContentsMargins(20, 20, 20, 20)
self.setLayout(hbox)
self.setGeometry(300, 300, 250, 180)
self.setWindowTitle('QComboBox')
self.show()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
#!/usr/bin/python
import sys
from PyQt5.QtWidgets import(QWidget, QLineEdit, QHBoxLayout, QPushButton,
QComboBox, QApplication)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
data = ['sky', 'cloud', 'grass', 'water', 'glass', 'forest',
'rock', 'light', 'brittle', 'water', 'smoke'
]
self.combo = QComboBox(self)
self.combo.setMinimumWidth(90)
self.combo.addItems(data)
self.lineEdit = QLineEdit()
self.lineEdit.setMinimumWidth(90)
btn = QPushButton("Find")
btn.clicked.connect(self.onClicked)
hbox.addWidget(self.combo)
hbox.setSpacing(20)
hbox.addWidget(self.lineEdit)
hbox.setSpacing(20)
hbox.addWidget(btn)
self.setContentsMargins(20, 20, 20, 20)
self.setLayout(hbox)
self.move(300, 300)
self.setWindowTitle('QComboBox')
self.show()
def onClicked(self):
data = self.lineEdit.text()
idx = self.combo.findText(data)
if idx != -1:
self.combo.setCurrentIndex(idx)
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
This signal is emitted when a new item has been activated (selected). The index is the position of the item in the combobox. , This signal is emitted when a new item has been activated (selected). string is the selected string. , QComboBox provides two different constructors. The simplest constructor creates an "old-style" combobox in Motif (or Aqua) style: , This signal is emitted when a new item has been set to current. The index is the position of the item in the combobox.
QComboBox provides two different constructors. The simplest constructor creates an "old-style" combobox in Motif (or Aqua) style:
QComboBox * c = new QComboBox(this, "read-only combobox");
The other constructor creates a new-style combobox in Motif style, and can create both read-only and editable comboboxes:
QComboBox * c1 = new QComboBox(FALSE, this, "read-only combobox");
QComboBox * c2 = new QComboBox(TRUE, this, "editable combobox");
Example:
static
const char * items[] = {
"red",
"green",
"blue",
0
};
combo - > insertStrList(items);
Click the Launch button to run the CustomComboBox Demo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.,Click the Launch button to run the ComboBox Demo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index. ,Click the Launch button to run the ComboBox2 Demo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index. ,Here's the code from ComboBoxDemo.java that registers and implements an action listener on the combo box:
String[] petStrings = {
"Bird",
"Cat",
"Dog",
"Rabbit",
"Pig"
};
//Create the combo box, select item at index 4.
//Indices start at 0, so 4 specifies the pig.
JComboBox petList = new JComboBox(petStrings);
petList.setSelectedIndex(4);
petList.addActionListener(this);
public class ComboBoxDemo...implements ActionListener {
...
petList.addActionListener(this) {
...
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox) e.getSource();
String petName = (String) cb.getSelectedItem();
updateLabel(petName);
}
...
}
String[] patternExamples = {
"dd MMMMM yyyy",
"dd.MM.yy",
"MM/dd/yy",
"yyyy.MM.dd G 'at' hh:mm:ss z",
"EEE, MMM d, ''yy",
"h:mm a",
"H:mm:ss:SSS",
"K:mm a,z",
"yyyy.MMMMM.dd GGG hh:mm aaa"
};
...
JComboBox patternList = new JComboBox(patternExamples);
patternList.setEditable(true);
patternList.addActionListener(this);
JComboBox petList = new JComboBox(intArray);
...
ComboBoxRenderer renderer = new ComboBoxRenderer();
renderer.setPreferredSize(new Dimension(200, 130));
petList.setRenderer(renderer);
petList.setMaximumRowCount(3);
class ComboBoxRenderer extends JLabel
implements ListCellRenderer {
...
public ComboBoxRenderer() {
setOpaque(true);
setHorizontalAlignment(CENTER);
setVerticalAlignment(CENTER);
}
/*
* This method finds the image and text corresponding
* to the selected value and returns the label, set up
* to display the text and image.
*/
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
//Get the selected index. (The index parameter isn't
//always valid, so just use the value.)
int selectedIndex = ((Integer) value).intValue();
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
//Set the icon and text. If icon was null, say so.
ImageIcon icon = images[selectedIndex];
String pet = petStrings[selectedIndex];
setIcon(icon);
if (icon != null) {
setText(pet);
setFont(list.getFont());
} else {
setUhOhText(pet + " (no image available)",
list.getFont());
}
return this;
}
...
}