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
Related
I want to be able to change page of QStackedWidget with some kind of animation (like fade in/out or others...)
after some research I find out maybe its possible with QGraphicsOpacityEffect, then I found this codes in here
Fade In Your Widget
// w is your widget
QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(this);
w->setGraphicsEffect(eff);
QPropertyAnimation *a = new QPropertyAnimation(eff,"opacity");
a->setDuration(350);
a->setStartValue(0);
a->setEndValue(1);
a->setEasingCurve(QEasingCurve::InBack);
a->start(QPropertyAnimation::DeleteWhenStopped);
Fade Out Your Widget
// w is your widget
QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(this);
w->setGraphicsEffect(eff);
QPropertyAnimation *a = new QPropertyAnimation(eff,"opacity");
a->setDuration(350);
a->setStartValue(1);
a->setEndValue(0);
a->setEasingCurve(QEasingCurve::OutBack);
a->start(QPropertyAnimation::DeleteWhenStopped);
connect(a,SIGNAL(finished()),this,SLOT(hideThisWidget()));
// now implement a slot called hideThisWidget() to do
// things like hide any background dimmer, etc.
but looks like these codes have some problem when used in QWidget inside of QStackedWidget i mean widget successfully fade in and out, but after animation finish if I minimize the windows the widget will disappear completely! (Im still able to see widget in bottom right corner of my window, looks like its pos changed?!)
btw my program is frameless.
thanks for help.
here is a example from my problem
test.cpp
Test::Test(QWidget *parent)
: CustomMainWindow(parent)
{
ui.setupUi(this);
setShadow(ui.bg_app);
connect(ui.close_app_btn, &QPushButton::clicked, this, &QWidget::close);
connect(ui.minimize_app_btn, &QPushButton::clicked, this, &QWidget::showMinimized);
QGraphicsOpacityEffect* eff = new QGraphicsOpacityEffect(this);
ui.checking->setGraphicsEffect(eff); // checking is my widget inside of QStackedWidget.
QPropertyAnimation* a = new QPropertyAnimation(eff, "opacity");
a->setDuration(350);
a->setStartValue(0);
a->setEndValue(1);
a->setEasingCurve(QEasingCurve::InBack);
a->start(QPropertyAnimation::DeleteWhenStopped);
}
CustomMainWindow.cpp
CustomMainWindow::CustomMainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
setAttribute(Qt::WA_TranslucentBackground);
}
void CustomMainWindow::setShadow(QWidget* window)
{
QGraphicsDropShadowEffect* windowShadow = new QGraphicsDropShadowEffect;
windowShadow->setBlurRadius(9.0);
windowShadow->setColor(palette().color(QPalette::Highlight));
windowShadow->setOffset(0.0);
window->setGraphicsEffect(windowShadow);
}
when I run my program with this code, at first its successfully Fade In, but if I for example minimize the window the widget move from its original position to somewhere else, look at this gif
Note: MainWindow is the name of my class.
Header file:
//...
private slots:
void animationStackedWidgets();
void whenAnimationFinish();
//....
CPP file:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->button, &QPushButton::clicked, this, &MainWindow::animationStackedWidgets);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::animationStackedWidgets()
{
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(this);
ui->stackedWidget->setGraphicsEffect(effect);
QPropertyAnimation *anim = new QPropertyAnimation(effectSw,"opacity");
anim->setDuration(350);
anim->setStartValue(0);
anim->setEndValue(1);
anim->setEasingCurve(QEasingCurve::InBack);
anim->start(QPropertyAnimation::DeleteWhenStopped);
connect(anim, SIGNAL(finished()), this, SLOT(whenAnimationFinish()));
}
void MainWindow::whenAnimationFinish()
{
ui->stackedWidget->setGraphicsEffect(0); // remove effect
}
I have so many buttons on a dialog and I want to change style sheets of them under some conditions.
Button object names are like below:
btn_1
btn_2
btn_3
..
btn_20
When I clicked one of these numerical buttons and later to another simple button, I want to change first clicked numerical button style sheet. How can I access that selected numerical button?
Edit:
What I mean by picture
I am trying to set colors of left column buttons (has numerically ordered object names) with right column buttons. User will be clicked numerical buttons first and then color named buttons.
You have to use the setStyleSheet method but you have to keep the reference of the button pressed, and that can be done using the sender method that returns the object that emitted the signal.
#include <QtWidgets>
class MainWindow: public QMainWindow{
Q_OBJECT
public:
MainWindow(QWidget *parent=nullptr):
QMainWindow(parent),
current_button(nullptr)
{
QWidget *widget = new QWidget;
setCentralWidget(widget);
QHBoxLayout *hlay = new QHBoxLayout(widget);
QVBoxLayout *number_lay = new QVBoxLayout;
QVBoxLayout *color_lay = new QVBoxLayout;
hlay->addLayout(number_lay);
hlay->addLayout(color_lay);
for(int i=0; i<20; i++){
QPushButton *button = new QPushButton(QString("btn_%1").arg(i+1));
connect(button, &QPushButton::clicked, this, &MainWindow::number_clicked);
number_lay->addWidget(button);
}
color_lay->addStretch();
for(const QString & colorname: {"Red", "Green", "Blue"}){
QPushButton *button = new QPushButton(colorname);
connect(button, &QPushButton::clicked, this, &MainWindow::color_clicked);
color_lay->addWidget(button);
button->setProperty("color", colorname.toLower());
button->setStyleSheet(QString("background-color: %1").arg(colorname));
}
color_lay->addStretch();
}
private slots:
void number_clicked(){
current_button = qobject_cast<QPushButton *>(sender());
}
void color_clicked(){
if(current_button){
QString colorname = sender()->property("color").toString();
current_button->setStyleSheet(QString("background-color: %1").arg(colorname));
}
}
private:
QPushButton *current_button;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "main.moc"
When you click on the first button, get its name using the method objectName(), then when you need to change the style, just specify in the method
setStyleSheet(QString(QPushButton#) + button->objectName() + QString("{ ... }");
I can write the example-program, but I do not fully understand what you want
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.
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
I've made some QPushbuttons like QPushButton **btn and I want to know when the user clicks on one of them using QMouseEvent here is the code but this idea does not work at all any ideas??
void Game::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
btn[ev->x()][ev->y()].setStyleSheet("background-color : black;");
}
else
{
btn[ev->x()][ev->y()].setStyleSheet("background-color : red;");
}
that else part is for right click
and here is the code that generates the buttons
void Game::MakeButton()
{
btn = new ApButton*[column];
hrztl = new QHBoxLayout[column];
hrztl->setSpacing(0);
for(int i=0; i<column;i++)
{
btn[i] = new ApButton[row];
for(int j=0; j<row; j++)
{
btn[i][j].setRowCol(i,j);
btn[i][j].setFixedSize(50,50);
hrztl[i].addWidget(&btn[i][j]);
}
ui->MainLayout->addLayout(&hrztl[i]);
}
ui->MainLayout->setSpacing(0);
}
ApButton is a class that inherits QPushButton
This is a good example of use for a QSignalMapper, as seen there: http://qt-project.org/doc/qt-5.0/qtcore/qsignalmapper.html#details
ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL(mapped(QString)),
this, SIGNAL(clicked(QString)));
setLayout(gridLayout);
}
In that example, every button is identified by its title, as a QString. The mapper allows you to retrieve the corresponding button's title when one of them is clicked.
Switch your
Game::mousePressEvent(QMouseEvent *e)
to
ApButton::mousePressEvent(QMouseEvent *e)
since you are trying to implement the Press Event of the Button. If you only want to have the moment of the button being pressed and not changing Button behaviour with this, use a SIGNAL/SLOT connection instead of reimplementing the event (add to your creation):
connect(btn[i][j], SIGNAL(pressed()), this, SLOT(slotButtonPressed());
void Game::slotButtonPressed(){
//doSomething
}
use a QButtonGroup or the QSignalMapper if you need to identify more then one Button in a single method or use QObject::sender(), but this can be tricky sometimes.
I had a similar situations some times ago.. I had a QDialog and I had to dinamically add some QPushButton.. then I need to know on which button the user pressed.. so I needed something like:
connect( btn, SIGNAL( clicked(int) ),
this, SLOT( handle(int) ));
for instance a signal-slot connection with the id of the clicked button and a function for handle the click. The function is the same for each buttons and can handle the specific button because of the id..
Implementing this is quite simple subclassing QPushButton adding an id and a new signal..
Hope it's some help!
If Apbutton inherits QPushButton, why don't connect to clicked()?
then you can call QObject::sender()
On slot:
ApButton *but = dynamic_cast<ApButton*>QObject::sender()
if(but)
{
but->setStyleSheet("background-color : black;");
}
to get the clicked buttonbutton and set its stylesheet