How do I get content from a QCombobox item by selecting an item?

I made this code, but it returns the previous value.

Code:

from PyQt5.QtWidgets import *
from PyQt5.QtGui import * 
from PyQt5.QtCore import * 
import sys 
class LoginForm(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Test')
        layout = QGridLayout()
        choices = ['1', '2', '3']

        btHome = QPushButton('Button',self)
        btHome.clicked.connect(self.callback)

        self.CmbBx_Cod = QComboBox()
        self.CmbBx_Cod.addItem('Select a value')

        for choices in choices:
            self.CmbBx_Cod.addItem(choices)
        self.CmbBx_Cod.view().pressed.connect(self.callback)

        layout.addWidget(btHome, 0, 0)
        layout.addWidget(self.CmbBx_Cod, 0, 2)
        self.setLayout(layout)
        
    
    def callback(self):
        code = self.CmbBx_Cod.currentText()
        print(f'code {code} selected!')

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    form = LoginForm() 
    form.show() 
    sys.exit(app.exec()) 

When I click the button I have the value I want, but I wanted it when I selected a code. Is there any other method of doing this?

Upvotes: 1

Views: 53

Answers (1)

eyllanesc
eyllanesc

Reputation: 243965

Explanation

In the first place, it should be understood that the pressed signal is emitted as soon as the mouse is placed with the button pressed on an item, but that is not used by the QComboBox to update the current text, but rather for stability the clicked signal that is emitted when the mouse is released, so in your logic you are trying to get the current text before it is updated so you get that unexpected behavior.

Proper solution

If you want to get the item pressed then you should not use the QComboBox but directly the QModelIndex sent in the signal:

def callback(self, index):
    code = index.data()
    print(f'code {code} selected!')

If instead you want to get the displayed text after releasing the mouse then you can use the clicked signal of the view, or better the currentTextChanged or currentIndexChanged signal.

class LoginForm(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Test")
        layout = QGridLayout()
        choices = ["1", "2", "3"]

        btHome = QPushButton("Button", self)
        btHome.clicked.connect(self.callback)

        self.CmbBx_Cod = QComboBox()
        self.CmbBx_Cod.addItem("Select a value")

        for choices in choices:
            self.CmbBx_Cod.addItem(choices)
        self.CmbBx_Cod.currentTextChanged.connect(self.callback)

        layout.addWidget(btHome, 0, 0)
        layout.addWidget(self.CmbBx_Cod, 0, 2)
        self.setLayout(layout)

    def callback(self, code):
        print(f"code {code} selected!")

If you want to get the current text by pressing the button then you must create another slot:

class LoginForm(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Test")
        layout = QGridLayout()
        choices = ["1", "2", "3"]

        btHome = QPushButton("Button", self)
        btHome.clicked.connect(self.button_callback)

        self.CmbBx_Cod = QComboBox()
        self.CmbBx_Cod.addItem("Select a value")

        for choices in choices:
            self.CmbBx_Cod.addItem(choices)
        self.CmbBx_Cod.currentTextChanged.connect(self.combo_callback)

        layout.addWidget(btHome, 0, 0)
        layout.addWidget(self.CmbBx_Cod, 0, 2)
        self.setLayout(layout)

    def button_callback(self):
        self.printer(self.CmbBx_Cod.currentText())

    def combo_callback(self, code):
        self.printer(code)

    def printer(self, code):
        print(f"code {code} selected!")

Upvotes: 1

Related Questions