Hi, everyone,
I'm working on a Qt6/C++ Qt Widgets application using QMainWindow and QTabWidget.
One tab embeds a QWebEngineView (in a tab named "Browser").
Another tab (called "Vocabulary") displays custom CardWidgets.
Each of which includes a QToolButton with a QMenu.
Issue:
When the app starts (the Vocabulary tab is active), everything works fine — the menu shows as expected when the button is clicked.
But after I switch to the Browser tab (with QWebEngineView) and then return to Vocabulary, the QToolButton click is detected but the menu no longer appears.
There are no crashes or warnings, and the QToolButton is still visible and responsive — just no menu.
CardWidget constructor snippet:
CardWidget::CardWidget(const QVariantList& data, QWidget *parent)
: QWidget(parent), expanded(false), currentRating(0)
{
this->id = data[0].toInt();
this->word = data[1].toString();
setCursor(Qt::PointingHandCursor); // Cursor on hover
setStyleSheet(R"(
QWidget {
border: 1px solid transparent;
border-radius: 8px;
padding: 8px;
}
QWidget:hover {
border: 2px solid #3498db;
}
)");
QVBoxLayout* mainLayout = new QVBoxLayout(this);
// Top Layout
QHBoxLayout* topLayout = new QHBoxLayout();
titleLabel = new QLabel(data[1].toString());
titleLabel->setStyleSheet("font-weight: bold; font-size: 16px;");
topLayout->addWidget(titleLabel);
menuButton = new QToolButton();
menuButton->setText("⋮");
menuButton->setPopupMode(QToolButton::InstantPopup);
menuButton->installEventFilter(this);
QMenu* menu = new QMenu();
QAction* editAction = menu->addAction("Edit");
QAction* deleteAction = menu->addAction("Delete");
menuButton->setMenu(menu);
menuButton->setFocus();
topLayout->addWidget(menuButton);
connect(editAction, &QAction::triggered, this, [this](){
emit CardWidget::editRequested(this->id);
});
connect(deleteAction, &QAction::triggered, this, [this](){
emit CardWidget::deleteRequested(this->id);
});
mainLayout->addLayout(topLayout);
// Expandable area
expandableArea = new QWidget();
QVBoxLayout* expandLayout = new QVBoxLayout(expandableArea);
QStringList labels = { "Part of Speech", "Meaning", "Example", "Synonyms", "Antonyms", "Notes" };
for (int i = 2; i < 8 && i < data.size(); ++i) {
QLabel* label = new QLabel(QString("<b>%1:</b> %2").arg(labels[i - 2], data[i].toString()));
label->setWordWrap(true);
expandLayout->addWidget(label);
}
expandableArea->setVisible(false);
mainLayout->addWidget(expandableArea);
// Star Rating
int rating = data[8].toInt();
QHBoxLayout* starsLayout = new QHBoxLayout();
for (int i = 0; i < 5; ++i) {
QPushButton* star = new QPushButton("☆");
star->setFlat(true);
star->setStyleSheet("font-size: 20px; color: gold;");
starButtons.append(star);
starsLayout->addWidget(star);
setRating(rating);
connect(star, &QPushButton::clicked, this, [this, i]() {
setRating(i+1);
});
}
mainLayout->addLayout(starsLayout);
}
In MainWindow
DictionaryApp::DictionaryApp(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::DictionaryApp)
{
ui->setupUi(this);
ui->statusBar->hide();
browser = new QWebEngineView();
QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(ui->browser_container->layout());
if(layout)
{
layout->insertWidget(1, browser);
}
pool = new QThreadPool();
initDB();
full_refresh_vocabTab();
}
full_refresh_vocabTab function:
void DictionaryApp::full_refresh_vocabTab()
{
QList<QVariantList> records = loadFromDB();
QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(ui->vocabListContainer->layout());
if (!layout) {
qDebug() << "Error: No layout set for vocabListContainer";
return;
}
// Clear previous cards if needed
QLayoutItem* item;
while ((item = layout->takeAt(0)) != nullptr) {
if (item->widget()) delete item->widget();
delete item;
}
// Add new cards
for (const QVariantList& row : records) {
CardWidget* card = new CardWidget(row);
cards.append(card);
layout->addWidget(card);
connect(card, &CardWidget::editRequested, this, &DictionaryApp::onEditRequested);
connect(card, &CardWidget::deleteRequested, this, &DictionaryApp::onDeleteRequested);
connect(card, &CardWidget::ratingChanged, this, &DictionaryApp::full_refresh_vocabTab);
}
}
What I've Tried
eventFilter() confirms that the button is receiving mouse clicks even after the tab switch.
The menu works only until I visit the QWebEngineView tab. Returning to the Vocabulary tab causes the menu to stop opening.
There are no errors in the debug output.
Tried removing/re-adding the widget — no change.
Question:
What might cause a QToolButton's QMenu to stop appearing after switching to a tab containing a QWebEngineView and then returning?
Versions:
Qt6.9
Qt Creator 13.0.0
OS: Fedora