I am trying to create a drop down button using QToolBar.
I tried to do that using the following strategy:
http://qt-project.org/forums/viewthread/5377
The problem is that the button doesn't respond immediately when I click on it. It takes several clicks to make the menu appear.
I guess I am putting the code in the wrong place, but where else should I put it?
Here is my code:
Proto::Proto(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Proto)
{
ui->setupUi(this);
QMenu *menu = new QMenu("Menu");
QWidgetAction *action = new QWidgetAction(this);
QPushButton *button2 = new QPushButton("Click me", menu);
action->setDefaultWidget(button2);
menu->addAction(action);
ui->btnVolume->setMenu(menu);
}
Please, anyone can help me?
Thanks in advance,
Seems like you forget to connect your button to a slot (or at least, it's not shown in the piece of code you posted). I just added the connect() statement like that
QPushButton *button2 = new QPushButton("Click me", menu);
connect(button2, SIGNAL(clicked()), SLOT(dosmth()));
action->setDefaultWidget(button2);
and then implemented this simple dosmth() Q_SLOT
void MainWindow::dosmth() {
qDebug() << "Hi";
}
and at each button click, i get this on the console:
Hi
Hi
Hi
Related
I have a simple flow
Click on QPushButton
QMenu with a couple of actions appears
Navigate through the QMenu using key clicks or mouse move.
(Triggering actions from code isn't a way, it should be a clean GUI test).
QTest::keyClick(m_menu, Qt::Key::Key_Down); - doesn't seem to work for me.
Simple example:
#include "mainwindow.h"
#include <QTest>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_button = new QPushButton("My Button", this);
m_button->setFixedSize(100,50);
m_menu = new QMenu("&Menu");
m_menu->addAction("&test1");
m_menu->addAction("&test2");
m_menu->addAction("&test3");
m_menu->addAction("&test4");
m_menu->addAction("&test5");
m_menu->addAction("&test6");
connect(m_button, SIGNAL (released()), this, SLOT (handleButton()));
}
void MainWindow::handleButton()
{
m_menu->exec(m_button->mapToGlobal(QPoint(20,20)));
QTest::qWait(2000);
for(int i = 0 ;i<=5;i++){
QTest::keyClick(m_menu, Qt::Key::Key_Down);
QTest::qWait(1000);
QTest::mouseMove(m_menu, QPoint(0,20));
QTest::qWait(1000);
}
}
MainWindow::~MainWindow()
{
}
Thanks to vahancho I found work around.
QMenu.exec() is executing synchronously. So, to have an opportunity to provide some input when menu is opened we should use next template:
QTimer::singleShot(0, [menu]()
{
//code that should be executed
});
menu->exec();
I want to create a combobox inside a message box and return the selected value to be used later.
I can do the same on the window itself but not sure how to do that inside a combobox.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->comboBox->addItem("Red");
ui->comboBox->addItem("Blue");
ui->comboBox->addItem("Green");
ui->comboBox->addItem("Yellow");
ui->comboBox->addItem("Pink");
ui->comboBox->addItem("Purple");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QMessageBox::about(this,"Choose color of rectangle", ui->comboBox->currentText() );
}
If I understand you correct you would like to show a combobox in a separate dialog window for the user to select some option.
One of the ways to do that, would be to subclass QDialog. If a combo field and a button to accept is sufficient the class could look as below:
class CustomDialog : public QDialog
{
public:
CustomDialog(const QStringList& items)
{
setLayout(new QHBoxLayout());
box = new QComboBox;
box->addItems(items);
layout()->addWidget(box);
QPushButton* ok = new QPushButton("ok");
layout()->addWidget(ok);
connect(ok, &QPushButton::clicked, this, [this]()
{
accept();
});
}
QComboBox* comboBox() { return box; }
private:
QComboBox* box;
};
To use the class object you can call exec to display it modally. Then you can verify whether the user accepted the choice by pressing the ok button and take proper action.
QStringList itemList({"item1", "item2", "item3"});
CustomDialog dialog(itemList);
if (dialog.exec() == QDialog::Accepted)
{
// take proper action here
qDebug() << dialog.comboBox()->currentText();
}
Similar approach is implemented in the QMessageBox class where a number of options can be specified to alter the displayed contents (for example button configuration or check box existance).
EDIT:
To use the sample code in your own project you should put the latter section I posted into your on_pushButton_clicked() slot. Substitute the itemList with your color names list. Then put the CustomDialog class to a separate file which you include in main and you should be good to go.
In a QWidget like QLabel, how can we set a "?" button, such that when clicked (or hovered) it should show some help text.
Also you can use QMenu instead of QPushButton + QLabel.
// Constructor
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotCustomMenu(QPoint)));
// slotCustomMenu(QPoint)
QMenu menu(this);
menu.addAction(this->toolTip());
menu.addAction(this->whatsThis());
menu.exec(QCursor::pos());
Easiest way to show help when hover QWidget: setToolTip(QString) and setToolTipDuration(int).
If you want a "?" button, just implement your own QWidget. Then via ui designer or directly in your code add QPushButton and QLabel on layout, and show your QLabel with help text in position of cursor when clicked(). Something like this:
{
// Constructor
...
m_mainLabel = new QLabel("Main text");
m_button = new QPushButton("?");
m_helpLabel = new QLabel("Help text");
connect(m_button, SIGNAL(clicked(bool)),
this, SLOT(slotShowOrHideHelpLabel(bool)));
QHBoxLayout *hBoxLayout = new QHBoxLayout;
hBoxLayout->addWidget(m_mainLabel);
hBoxLayout->addWidget(m_button);
setLayout(hBoxLayout);
}
void slotShowOrHideHelpLabel(bool showHelpLabel)
{
if (showHelpLabel)
{
m_helpLabel->show();
m_helpLabel->move(QCursor::pos());
}
else
{
m_helpLabel->hide();
}
}
I have created a overwrite dialog box as shown below in QT/C++
here is the code associated:
DialogOverwrite::DialogOverwrite(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogOverwrite)
{
ui->setupUi(this);
QPushButton *YesToAllButton = ui->buttonBox->button(QDialogButtonBox::YesToAll);
QPushButton *YesButton = ui->buttonBox->button(QDialogButtonBox::Yes);
QPushButton *NoToAllButton = ui->buttonBox->button(QDialogButtonBox::NoToAll);
QPushButton *NoButton = ui->buttonBox->button(QDialogButtonBox::No);
QPushButton *CancelButton = ui->buttonBox->button(QDialogButtonBox::Cancel);
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)),this,
SLOT(dialogButton(QAbstractButton*)));
}
DialogOverwrite::~DialogOverwrite()
{
delete ui;
}
void DialogOverwrite::dialogButton(QAbstractButton* aButton) {
QDialogButtonBox::StandardButton button = ui->buttonBox->standardButton(aButton);
switch (button) {
case QDialogButtonBox::YesToAll:
OverwriteAction = YES_TO_ALL;
break;
....
I have declared QPushButton *YesToAllButton ... in order to connect to the buttonbox design in the ui and triggered the signal clicked.
The triggered works fine but when trying to catch on which button I have clicked, I receive a "NoButton" instead of YesToAll or any other.
Did I miss something
Thanks
I'm working with the Qt KDE Necessitas project. I have a project built in Qt Creator and I am installing the apk on an emulator API-15 (also tested on API-10).
The following code is setup to clear the text of two different QLineEdit objects when a button is clicked, but this isn't the case. Randomly, only one of the two QLineEdit objects are cleared.
mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
public slots:
void slotClear();
private:
QLineEdit* line1;
QLineEdit* line2;
//...
};
mainwindow.cpp:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout* mainLayout = new QVBoxLayout;
QFormLayout* form = new QFormLayout;
line1 = new QLineEdit;
form->addRow(tr("Line 1: "), line1);
line2 = new QLineEdit;
form->addRow(tr("Line 2:"), line2);
QPushButton* button = new QPushButton;
mainLayout->addLayout(form);
mainLayout->addWidget(button);
QWidget* centralWid = new QWidget(this);
centralWid->setLayout(mainLayout);
this->setCentralWidget(centralWid);
connect(button, SIGNAL(clicked()), this, SLOT(slotClear()));
}
void MainWindow::slotClear()
{
line1->clear();
line2->clear();
}
//...
Calling the function QLineEdit::setText("") produces the same results. Additionally, connecting the clicked() signal from the button directly to the clear() slot of the QLineEdit has no effect.
I haven't been programming in Qt for very long, so I am unsure if there is something I am doing wrong. Is anybody seeing something needs to be corrected in order to have the text cleared from BOTH QLineEdits? I am not sure if this is unique to Qt itself or Qt Necessitas. Any input would be greatly appreciated.
EDIT
I have also just noticed that entering text in one line, switching to another line and entering text there, and then switching back to the original line results in the original text being erased once the field is clicked (note, the button was never clicked). I think this is a pretty clear indication that something funky is going on.
EDIT 2
Registered as a bug with KDE