QComboBox higlighted works differently between Qt C++ and PySide6
-
Hello. I had an application that I built with QT C++. On my QComboBox, I have used highlighted signal. It triggers everytime the QComboBox is:
- Expanded
- Mouse moved from one item to another:
The screenshot below shows the signal triggering by simply expanding the QComboBox:
void SettingsWindow::on_serialPortInfoListBox_highlighted(int index) { qDebug("highligted \n"); }
I am trying to implement the same on my PySide6 application.
I have connected the signal to the slot:
self.ui_serialPortInfoListBox.highlighted.connect(self.Combo_higlighted)
def Combo_higlighted(self): print("Highlighted")
But the signal is not triggered when I am expanding the QComboBox
I would like to understand what could be the reason. Is that expected behaviour?
-
Hello. I had an application that I built with QT C++. On my QComboBox, I have used highlighted signal. It triggers everytime the QComboBox is:
- Expanded
- Mouse moved from one item to another:
The screenshot below shows the signal triggering by simply expanding the QComboBox:
void SettingsWindow::on_serialPortInfoListBox_highlighted(int index) { qDebug("highligted \n"); }
I am trying to implement the same on my PySide6 application.
I have connected the signal to the slot:
self.ui_serialPortInfoListBox.highlighted.connect(self.Combo_higlighted)
def Combo_higlighted(self): print("Highlighted")
But the signal is not triggered when I am expanding the QComboBox
I would like to understand what could be the reason. Is that expected behaviour?
@lukutis222
As you have shown in your C++, thehighlighted()
signal sends anint index
parameter to attached slots. So why do you omit this from your Python slot? This may cause Python/PySide6 not to match it to the signal, I don't know. Start by changing to:def Combo_higlighted(self, index): # or def Combo_higlighted(self, index: int):
-
@lukutis222
As you have shown in your C++, thehighlighted()
signal sends anint index
parameter to attached slots. So why do you omit this from your Python slot? This may cause Python/PySide6 not to match it to the signal, I don't know. Start by changing to:def Combo_higlighted(self, index): # or def Combo_higlighted(self, index: int):
@JonB
Well spotted but that does not seem to make any difference. -
@JonB
Well spotted but that does not seem to make any difference.@lukutis222
OK, then you are claiming theQComboBox.highlighted()
signal does not work at all from whatever version of PySide6 you are using. Create a totally standalone program (no.ui
file) which just creates a combobox and attach the slot to the signal. If that does not work show your code so others can check and then report as a bug. -
@lukutis222
OK, then you are claiming theQComboBox.highlighted()
signal does not work at all from whatever version of PySide6 you are using. Create a totally standalone program (no.ui
file) which just creates a combobox and attach the slot to the signal. If that does not work show your code so others can check and then report as a bug.I did not claim that QComboBox does not work.
I claim that it works differently on PySide6 vs QT C++
On PySide6 it does not generate a signal when QComboBox is expanded and we hover over the only item that exists in the QComboBox.
On QT C++ it generates a signal immediately when QComboBox is expanded.
This is a standalone PySide6 program to test the QComboBox:
# This Python file uses the following encoding: utf-8 import sys from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QComboBox from PySide6.QtCore import Qt class MainWindow(QWidget): def __init__(self): super().__init__() # Set up the layout layout = QVBoxLayout() # Create a QComboBox self.combo_box = QComboBox() # Add a single item to the combo box self.combo_box.addItem("Item 1") # Connect the highlighted signal to a slot method self.combo_box.highlighted.connect(self.on_item_highlighted) # Add the combo box to the layout layout.addWidget(self.combo_box) # Set the layout for the main window self.setLayout(layout) # Set the window title self.setWindowTitle("QComboBox Example") def on_item_highlighted(self, index): print(f"Item at index {index} highlighted") if __name__ == "__main__": app = QApplication(sys.argv) # Create an instance of the main window main_window = MainWindow() # Show the main window main_window.show() # Execute the application sys.exit(app.exec())
I have created an alternative project for C++:
#include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QComboBox> #include <iostream> class MainWindow : public QWidget { public: MainWindow(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); // Create a QComboBox QComboBox *comboBox = new QComboBox(this); // Add a single item to the combo box comboBox->addItem("Item 1"); // Connect the highlighted signal to a slot method connect(comboBox, QOverload<int>::of(&QComboBox::highlighted), this, &MainWindow::onItemHighlighted); // Add the combo box to the layout layout->addWidget(comboBox); // Set the layout for the main window setLayout(layout); // Set the window title setWindowTitle("QComboBox Example"); } private slots: void onItemHighlighted(int index) { std::cout << "Item at index " << index << " highlighted" << std::endl; } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // Create an instance of the main window MainWindow mainWindow; // Show the main window mainWindow.show(); // Execute the application return app.exec(); }
after expanding the QComboBox, I get the signal on C++ but not on the PySide6. I hope this is more clear now and we can get to the bottom of this
-
I did not claim that QComboBox does not work.
I claim that it works differently on PySide6 vs QT C++
On PySide6 it does not generate a signal when QComboBox is expanded and we hover over the only item that exists in the QComboBox.
On QT C++ it generates a signal immediately when QComboBox is expanded.
This is a standalone PySide6 program to test the QComboBox:
# This Python file uses the following encoding: utf-8 import sys from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QComboBox from PySide6.QtCore import Qt class MainWindow(QWidget): def __init__(self): super().__init__() # Set up the layout layout = QVBoxLayout() # Create a QComboBox self.combo_box = QComboBox() # Add a single item to the combo box self.combo_box.addItem("Item 1") # Connect the highlighted signal to a slot method self.combo_box.highlighted.connect(self.on_item_highlighted) # Add the combo box to the layout layout.addWidget(self.combo_box) # Set the layout for the main window self.setLayout(layout) # Set the window title self.setWindowTitle("QComboBox Example") def on_item_highlighted(self, index): print(f"Item at index {index} highlighted") if __name__ == "__main__": app = QApplication(sys.argv) # Create an instance of the main window main_window = MainWindow() # Show the main window main_window.show() # Execute the application sys.exit(app.exec())
I have created an alternative project for C++:
#include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QComboBox> #include <iostream> class MainWindow : public QWidget { public: MainWindow(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); // Create a QComboBox QComboBox *comboBox = new QComboBox(this); // Add a single item to the combo box comboBox->addItem("Item 1"); // Connect the highlighted signal to a slot method connect(comboBox, QOverload<int>::of(&QComboBox::highlighted), this, &MainWindow::onItemHighlighted); // Add the combo box to the layout layout->addWidget(comboBox); // Set the layout for the main window setLayout(layout); // Set the window title setWindowTitle("QComboBox Example"); } private slots: void onItemHighlighted(int index) { std::cout << "Item at index " << index << " highlighted" << std::endl; } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // Create an instance of the main window MainWindow mainWindow; // Show the main window mainWindow.show(); // Execute the application return app.exec(); }
after expanding the QComboBox, I get the signal on C++ but not on the PySide6. I hope this is more clear now and we can get to the bottom of this
@lukutis222 said in QComboBox higlighted works differently between Qt C++ and PySide6:
I did not claim that QComboBox does not work.
I claim that it works differently on PySide6 vs QT C++
I don't know why you are pointing out semantics: if the
highlighted()
signal does not work under PySide6 when it works under Qt6 with C++ then it "does not work" or "it's a bug".FWIW, I had knocked together the following, tested working under PySide2/Qt5 which is all I have:
import sys from PySide2 import QtWidgets # from PyQt5 import QtWidgets def window(): app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() cb = QtWidgets.QComboBox(w) cb.addItems(["Line 1", "Line 2", "Hello World!"]) w.setGeometry(100,100,200,50) cb.move(50,20) cb.highlighted.connect(lambda: print("highlighted slot")) w.show() sys.exit(app.exec_()) if __name__ == '__main__': window()
Now you have shown your C++ code, which you did not before. And I see you have
// Connect the highlighted signal to a slot method connect(comboBox, QOverload<int>::of(&QComboBox::highlighted), this, &MainWindow::onItemHighlighted);
Why do you use
QOverload<int>::of()
here? As I say I don't have Qt6, but from https://doc.qt.io/qt-6/qcombobox-members.html I do not see any multiple overloads of QComboBox::highlighted(), do you? Remove theQOverload<int>::of()
from theconnect()
statement: does that go through and work or do you get a C++ compilation error? If there really are multiple overloads ofhighlighted()
then you need to make the Python code pick between these just like the C++ code, so let us know.Does my example code work for you under PySide6? If not then I believe you have a PySide6 bug (unless as I said there really are multiple overloads in Qt6/PySide6).
-
@JonB
I removed the overload:connect(comboBox, &QComboBox::highlighted, this, &MainWindow::onItemHighlighted);
When the QComboBox is initially expanded, it still triggers a higlihted signal which is exactly what I want.
I have tested your code (just changed import to PySide6) and these are the results:
It does not generate a signal when the QComboBox is initially expanded, however, it generates a signal when hovering mouse over different items within QComboBox (which is expected).I want to be able to trigger the signal immediately after the QComboBox is expanded just like it works on C++.
Perhaps I am misunderstanding something? Are we supposed to get the highlighted signal when the QComboBox is initially expanded when there is only 1 item? Perhaps its the other way around - C++ generates an additional signal when it is not supposed to and PySide6 does not.
-
@JonB
I removed the overload:connect(comboBox, &QComboBox::highlighted, this, &MainWindow::onItemHighlighted);
When the QComboBox is initially expanded, it still triggers a higlihted signal which is exactly what I want.
I have tested your code (just changed import to PySide6) and these are the results:
It does not generate a signal when the QComboBox is initially expanded, however, it generates a signal when hovering mouse over different items within QComboBox (which is expected).I want to be able to trigger the signal immediately after the QComboBox is expanded just like it works on C++.
Perhaps I am misunderstanding something? Are we supposed to get the highlighted signal when the QComboBox is initially expanded when there is only 1 item? Perhaps its the other way around - C++ generates an additional signal when it is not supposed to and PySide6 does not.
@lukutis222 said in QComboBox higlighted works differently between Qt C++ and PySide6:
It does not generate a signal when the QComboBox is initially expanded,
For me my PySide2 does generate a signal on "initial expansion" of the combobox. Tested with just 1 entry in the combobox which I think is what you wanted.
If I look closely: when it starts up the one item is not shown highlighted in blue. When I click the "down arrow" to expand the item changes to highlighted blue and I get the signal. Do you see the same situation? Is that identical between the C++ and PySide6 versions? Is your PySide6 code identical in statement order and operation to your C++? You might print out the combo's
selectedIndex()
before expanding from C++ & PySide2. Are they both-1
? If one is0
and the other is-1
that would be significant.Are we supposed to get the highlighted signal when the QComboBox is initially expanded when there is only 1 item?
I don't know, but I get it in my code and PySide2.
Perhaps its the other way around - C++ generates an additional signal when it is not supposed to and PySide6 does not.
It doesn't work that way. PySide6 does not "generate" the signals. The underlying C++ library, which PySide6 has to link with, does the signal generation. PySide6 is supposed merely to act on that correctly. And the C++ does not "know" it is running under PySide.
Try playing to see if you can find they are in any different initial state which would explain the different behaviour. If not I suggest you post a minimal example (such as mine) of what you are using in both C++ and PySide6. Let those who have Qt6/PySide6 test these. If they differ then it is worth a bug report.
P.S.
Although it made no difference in my case (where things worked anyway) I would test connecting the signal before you add the first item as well as your after adding the item, just in case that makes a difference. -
Its really strange. It does seem like the item is being higlighted (changes color to blue) when the ComboBox is expanded but no signal is triggered. However, if I add more than 1 item to the ComboBox and hover over different items it will work fine.
@JonB said in QComboBox higlighted works differently between Qt C++ and PySide6:
Although it made no difference in my case (where things worked anyway) I would test connecting the signal before you add the first item as well as your after adding the item, just in case that makes a difference.
I have also though about that. The results are as following:
import sys from PySide6 import QtWidgets # from PyQt5 import QtWidgets def window(): app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() cb = QtWidgets.QComboBox(w) cb.addItems(["Line 1", "Line 2", "Hello World!"]) cb.highlighted.connect(lambda: print("highlighted slot")) w.setGeometry(100,100,200,50) cb.move(50,20) w.show() sys.exit(app.exec()) if __name__ == '__main__': window()```
Signal is not triggered when the ComboBox is expanded, it does trigger when hovering over different items.
import sys from PySide6 import QtWidgets # from PyQt5 import QtWidgets def window(): app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() cb = QtWidgets.QComboBox(w) cb.highlighted.connect(lambda: print("highlighted slot")) cb.addItems(["Line 1", "Line 2", "Hello World!"]) w.setGeometry(100,100,200,50) cb.move(50,20) w.show() sys.exit(app.exec()) if __name__ == '__main__': window()
The signal triggers immediately after the application is started (I did not even need to expand the QComboBox). However, it still does not trigger when expanded but works without issues when hovering over different items.
It really seems there might be something wrong with PySide6 ?
-
Its really strange. It does seem like the item is being higlighted (changes color to blue) when the ComboBox is expanded but no signal is triggered. However, if I add more than 1 item to the ComboBox and hover over different items it will work fine.
@JonB said in QComboBox higlighted works differently between Qt C++ and PySide6:
Although it made no difference in my case (where things worked anyway) I would test connecting the signal before you add the first item as well as your after adding the item, just in case that makes a difference.
I have also though about that. The results are as following:
import sys from PySide6 import QtWidgets # from PyQt5 import QtWidgets def window(): app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() cb = QtWidgets.QComboBox(w) cb.addItems(["Line 1", "Line 2", "Hello World!"]) cb.highlighted.connect(lambda: print("highlighted slot")) w.setGeometry(100,100,200,50) cb.move(50,20) w.show() sys.exit(app.exec()) if __name__ == '__main__': window()```
Signal is not triggered when the ComboBox is expanded, it does trigger when hovering over different items.
import sys from PySide6 import QtWidgets # from PyQt5 import QtWidgets def window(): app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() cb = QtWidgets.QComboBox(w) cb.highlighted.connect(lambda: print("highlighted slot")) cb.addItems(["Line 1", "Line 2", "Hello World!"]) w.setGeometry(100,100,200,50) cb.move(50,20) w.show() sys.exit(app.exec()) if __name__ == '__main__': window()
The signal triggers immediately after the application is started (I did not even need to expand the QComboBox). However, it still does not trigger when expanded but works without issues when hovering over different items.
It really seems there might be something wrong with PySide6 ?
@lukutis222 said in QComboBox higlighted works differently between Qt C++ and PySide6:
It does seem like the item is being higlighted (changes color to blue) when the ComboBox is expanded but no signal is triggered
That does not sound right. And is not what I see with PySide2/Qt5.
You did not check the
selectedIndex()
and its relation to the initial signal under both PySide & C++?Anyway, at this point I do not have PySide6 and it seems to work fine under PySide2. Verify your PySide6 is using the exact same version of Qt6 as you are using for your C++. Wait and see if someone else who has PySide6 tries/comments. Otherwise as I said produce an absolute minimal, identical PySide6 & Qt6/C++ test program and submit to Qt bug reports. (BTW: If you have/want to test PyQt6 to compare against PySide6 behaviour that can be revealing.)