I had a working program in Qt4. After porting it to Qt5, the QActions' icons no longer show in the QMenu; only the text shows. The icons show ok in the toolbar, but not in the menu. I've already set the app to disable "AA_DontShowIconsInMenus" to no avail. Here is a portion of the code:
pMenuBar = new QMenuBar(this);
pMenuBar->setObjectName(QString::fromUtf8("Menu Bar"));
pMenuBar->setGeometry(QRect(0, 0, 800, 27));
MyIcon.addFile(":/images/filenew.ico", QSize(), QIcon::Normal, QIcon::On);
pAction = new QAction(tr("&New"), this);
pAction->setIcon(MyIcon);
pAction->setIconVisibleInMenu(true);
pAction->setShortcuts(QKeySequence::New);
pAction->setStatusTip(tr("New"));
pMenuFile = new QMenu(pMenuBar);
pMenuFile->setObjectName(QString::fromUtf8("File Menu"));
// pMenuFile->menuAction()->setIconVisibleInMenu(true);
pMenuFile->addAction(pAction);
pMenuBar->addAction(pMenuFile->menuAction());
setMenuBar(pMenuBar);
I guess *.ico is not supported, try it with *.png.
You can check:
QImageReader::supportedImageFormats() and QImageWriter::supportedImageFormats()
Related
I want to get a Popup Widget to be shown when clicking on a QToolbutton.
This can be done by adding an action to the button itself.
The popup will contain a three buttons (update, create and cancel) and a text input field.
I have some sample code with only one button I have shared as a Github repository.
The most relevant part of the code is:
auto button = new QToolButton(this);
button->setText(" AA ");
auto popup = new Popup(button, this);
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
The result is as follow:
I have two issues I cannot solve:
Getting the popup widget to right align to the button.
Getting the popup widget to close when one of the buttons inside of it are clicked.
Right align the popup
There is already a similar question: Set position (to right) of Qt QPushButton popup menu.
I can add the suggested code:
void Popup::showEvent(QShowEvent*)
{
QPoint p = this->pos();
QRect geo = clickedButton->geometry();
this->move(p.x()+geo.width()-this->geometry().width(), p.y());
}
But only the content of the popup gets right aligned to the button, not the popup itself:
Closing the popup
If I click anywhere (but a widget) in the Popup it closes. I'm somehow fine with this.
But if I cannot manage to get a click on the button to close the popup.
I've tried to call the close() function but it only clears the content of the popup without closing it.
Can I get the button to trigger a signal and then close the popup?
I ask both questions as the same time, since they look very similar: both times it's the content and not the popup that is affected.
auto popup = new Popup(button, this);
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
Your Popup widget is not the actual popup, but just a widget inside the real popup.
So what you're moving is the widget inside the real popup and not the popup itself.
The solution in the question you linked to uses QMenu and it works with QMenu.
In your code replace
connect(button, &QToolButton::clicked, this, &MainWindow::showPopup);
auto updateButton = new QPushButton("Update");
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(updateButton);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
with
button->setPopupMode(QToolButton::InstantPopup);
auto menu = new Popup(button, this);
auto action = new QAction("Test");
menu->addAction(action);
button->setMenu(menu);
Change your Popup class to extend/inherit QMenu, uncomment the showEvent method and remove everything from the constructor.
EDIT
You can set a layout to the qmenu and add widgets to it.
auto menuLayout = new QGridLayout();
auto menuBtn1 = new QPushButton("Btn1");
auto menuBtn2 = new QPushButton("Btn2");
auto menuBtn3 = new QPushButton("Btn3");
menuLayout->addWidget(menuBtn1, 0, 0);
menuLayout->addWidget(menuBtn2, 0, 1);
menuLayout->addWidget(menuBtn3, 1, 0);
button->setPopupMode(QToolButton::InstantPopup);
auto menu = new Popup(button, this);
menu->setLayout(menuLayout);
When you use a layout it has margins that prevent alignment.
The QMenu of the Popup can be accessed through kinship but this must be accessed when the button is pressed as this is created when it is first shown.
popup.h
#ifndef POPUP_H
#define POPUP_H
#include <QWidget>
class QToolButton;
class Popup : public QWidget
{
Q_OBJECT
public:
explicit Popup(QWidget* parent=nullptr);
Q_SIGNALS:
void clicked();
};
#endif
popup.cpp
#include "popup.h"
#include<QWidget>
#include<QVBoxLayout>
#include<QPushButton>
Popup::Popup(QWidget* parent)
: QWidget(parent)
{
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addStretch();
auto updateButton = new QPushButton("Update");
layout->addWidget(updateButton);
connect(updateButton, &QPushButton::clicked, this, &Popup::clicked);
}
mainwindow.h
MainWindow::MainWindow()
{
auto widget = new QWidget;
setCentralWidget(widget);
auto layout = new QHBoxLayout(widget);
layout->addStretch();
auto button = new QToolButton;
button->setText(" AA ");
layout->addWidget(button);
auto popup = new Popup;
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
connect(popup, &Popup::clicked, [popup](){
if(QWidget *p = popup->parentWidget())
p->close();
});
}
I'm using QT 5.4.2 and trying to create a small panel at the bottom
of a subclassed QTreeWidget.
Here is the code:
void HmiScenarioAutoscriptPanel::searchEmitter() {
QWidget *child = new QWidget(ui->emitterTreeWidget);
//QMainWindow* child = new QMainWindow;
QLabel *labelSearch = new QLabel("Search");
QLineEdit *lineSearch = new QLineEdit();
lineSearch->setFixedSize(100, 20);
QHBoxLayout* layout = new QHBoxLayout(ui->emitterTreeWidget);
layout->setAlignment(Qt::AlignBottom);
layout->addWidget(child);
layout->addWidget(labelSearch);
layout->addWidget(lineSearch);
}
The label and search field correctly appear at the bottom of the tree,
however the fields overlap with the tree nodes (see image below).
Any idea why this behavior?
Ciao
Alf
enter image description here
It is not recommended to set layout on the tree widget. It is like other controls like a button, label etc..
I see that you are using designer. Add a blank widget (searchWidget) under the tree widget and then
void HmiScenarioAutoscriptPanel::searchEmitter() {
QWidget *child = new QWidget(ui->searchWidget);
//QMainWindow* child = new QMainWindow;
QLabel *labelSearch = new QLabel("Search", searchWidget);
QLineEdit *lineSearch = new QLineEdit(searchWidget);
lineSearch->setFixedSize(100, 20);
QHBoxLayout* layout = new QHBoxLayout(ui->searchWidget);
layout->setAlignment(Qt::AlignBottom);
layout->addWidget(child);
layout->addWidget(labelSearch);
layout->addWidget(lineSearch);
}
Just out of curiosity, why don't you add these using the designer as well?
I have tried to use QQuickWidget as background of my application.
I created 2 classes: KViewer (load QML file) and GUI (main GUI of application)
GUI.cpp
GUI::GUI(QWidget *parent)
: QWidget(parent)
{
setFixedSize(500, 500);
QHBoxLayout* layout = new QHBoxLayout(this);
KViewer* viewer = new KViewer(this);
viewer->resize(size());
QLabel* label = new QLabel("TEXT HERE");
label->setFixedSize(400, 400);
label->setAlignment(Qt::AlignCenter);
label->setStyleSheet("QLabel {"
"background-color: yellow;"
"border-radius: 6px;"
"}");
layout->addWidget(label);
}
and KViewer.cpp
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setSpacing(0);
layout->setMargin(0);
QQuickWidget* mQQuickWidget = new QQuickWidget;
mQQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
mQQuickWidget->setSource(QUrl("qrc:/qml/main.qml"));
layout->addWidget(mQQuickWidget);
what I received
Label corner with border-radius problem
There's something wrong at corner of my label. Why black color here? Please help me solve this problem. Is there any other ways to use QML object as background of Qt application?
I have already test some demo before, you maybe need to use Absolute positioning to layout your widgets in gui.cpp.
I want to overlay a QGLWidget with clickable buttons.
I'm using a QGraphicsView and setting the viewport to a QGLWidget. Then I'm adding a layout to the QGraphicsView, and adding several QPushButtons to that.
The Buttons display correctly, HOWEVER they are not clickable.
Here is my code:
QGraphicsView* view = ui->gView;
QGLWidget* gl = new QGLWidget(QGLFormat(QGL::SampleBuffers));
view->setViewport(gl);
QPushButton* push = new QPushButton("Click me");
QHBoxLayout* h = new QHBoxLayout;
QPushButton* wo = new QPushButton("Wo");
h->addWidget(wo);
h->addWidget(push);
view->setLayout(h);
Is there a simple way I can make the buttons get the clicks when the mouse is above them, and QGLWidget get the clicks otherwise?
How to change the size of a button in the QFileDialog? I tried the below code; it compiles but the application exits unexpectedly if I try to load the file dialogue.
Please let me know what is going wrong. I am new to QT. :(
QFileDialog *fdiag = new QFileDialog();
QGridLayout *glayout = static_cast <QGridLayout*>(fdiag->layout());
QLayoutItem *li = glayout->itemAtPosition(3,3);
QRect buttonRect = li->geometry() ;
int newHeight = buttonRect.height() + 20;
int newWidth = buttonRect.height() + 20;
buttonRect.setHeight(newHeight);
buttonRect.setWidth(newWidth);
li->setGeometry(buttonRect);
fdiag->resize(720,480);
fdiag->setWindowTitle("Media Folder");
fdiag->exec();
You could just use a stylesheet:
QFileDialog *fdiag = new QFileDialog;
fdiag->setStyleSheet("QPushButton{min-height: 40px; min-width: 200px;}");
Or if you want to resize a specific button only:
QDialogButtonBox *box = fdiag->findChild<QDialogButtonBox*>();
if(box)
{
QPushButton *button = box->button(QDialogButtonBox::Open);
if(button)
{
button->setMinimumHeight(40);
button->setMinimumWidth(200);
}
}
As i've got this problem recently, with Qt5 - for some reasons in Qt4 it worked - you need to make sure, that Qt returns not Null from layout().
You need to initialize the System dialog with the Option QFileDialog::DontUseNativeDialog, e.g. with dlg->setOption(QFileDialog::DontUseNativeDialog, true);