I have written a simple program where the dialog window opens in maximized mode and there are some labels and buttons set to this window. I set a gridlayout to my window and added the labels and buttons to the layout , and my code worked fine. When I try to use scrollarea instead of the pink label(which is in row=1 and column=1), I don't get the same result that I got from putting the pink label in (row=1 and column=1).
I know that when labels or buttons are supposed to be in a scrollarea, I must declare a widget and setwidget to the scrollarea, then declare a layout and setlayout to the widget. But for this case(that the scrollarea itself must be in a layout) I don't know what to do.
Here is the code:
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QScrollArea>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
QLabel *red_label;
QLabel *pink_label;
QLabel *yellow_label;
QScrollArea *scrollArea;
QPushButton *button_one;
QPushButton * button_two;
QPushButton * button_three;
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include <QLabel>
#include <QGridLayout>
#include <QWidget>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
this->setWindowState(this->windowState() ^ Qt::WindowMaximized);
this->setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint |
Qt::WindowMaximizeButtonHint);
red_label = new QLabel(this);
red_label->showFullScreen();
red_label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
red_label->setLayoutDirection(Qt::RightToLeft);
red_label->setObjectName("forlumha_Name");
red_label->setStyleSheet(
"QLabel#forlumha_Name {"
"background-color:red;"
"}"
);
/* pink_label = new QLabel(this);
pink_label ->showFullScreen();
pink_label ->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
pink_label ->setLayoutDirection(Qt::RightToLeft);
pink_label ->setObjectName("forlumha_Name");
pink_label ->setStyleSheet(
"QLabel#forlumha_Name {"
"background-color:pink;"
"}"
);*/
yellow_label = new QLabel(this);
yellow_label->showFullScreen();
yellow_label->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
yellow_label->setLayoutDirection(Qt::RightToLeft);
yellow_label->setObjectName("forlumha_Name");
yellow_label->setStyleSheet(
"QLabel#forlumha_Name {"
"background-color:yellow;"
"}"
);
button_one = new QPushButton(this);
button_one->setFixedSize(50,50);
button_two = new QPushButton(this);
button_two->setFixedSize(50,50);
button_three = new QPushButton(this);
button_three->setFixedSize(50,50);
//.......adding scrollarea........//
scrollArea = new QScrollArea(this);
//..........set layouts......//
QGridLayout *layout = new QGridLayout();
this->setLayout( layout );
layout->addWidget(red_label,0,0,15,1);
layout->addWidget(yellow_label,0,1,1,1);
//layout->addWidget(pink_label,1,1,14,1);
layout->addWidget(scrollArea,1,1,14,1);
layout->addWidget(button_one,6,2,1,1);
layout->addWidget(button_two,7,2,1,1);
layout->addWidget(button_three,8,2,1,1);
}
Dialog::~Dialog()
{
delete ui;
}
main.cpp:
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
The above code output :
When I comment the pink_label parts and declare a scrollArea and put it in row=1 and column=1,the output is :
Related
In my sample application, the MainWindow closes instead of the dialog window. Why is that and how do I change it?
I've tried setQuitOnLastWindowClosed() but it didn't have any effect.
When clicking the x in the top right corner, the dialog window closes and the MainWindow remains open as expected. But that's of course not what I want.
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDialog>
#include <QWidget>
#include <QPushButton>
#include <QHBoxLayout>
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
void on_mainWindowBtn();
void on_closeBtn();
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *mainWindowWidget = new QWidget(this);
QHBoxLayout *mainWindowHBox = new QHBoxLayout();
QPushButton *mainWindowPushButton = new QPushButton();
mainWindowPushButton->setText("Open Dialog Window");
mainWindowHBox->addWidget(mainWindowPushButton);
mainWindowWidget->setLayout(mainWindowHBox);
this->setCentralWidget(mainWindowWidget);
connect(mainWindowPushButton, &QPushButton::released, this, &MainWindow::on_mainWindowBtn);
}
void MainWindow::on_mainWindowBtn()
{
QDialog *newDialog = new QDialog();
QHBoxLayout *newHBox = new QHBoxLayout();
QPushButton *closeBtn = new QPushButton();
closeBtn->setText("Close Dialog Window");
newHBox->addWidget(closeBtn);
newDialog->setLayout(newHBox);
newDialog->setModal(true);
connect(closeBtn, &QPushButton::released, this, &MainWindow::on_closeBtn);
newDialog->exec();
}
void MainWindow::on_closeBtn()
{
close(); // closes the MainWindow but not the dialog window
}
MainWindow::~MainWindow()
{
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(false);
MainWindow w;
w.show();
return a.exec();
}
In this code which can able to play video and play *.mp3. code works properly,in my mainwindow.ui I added widget called widgetGif by drag and drop .This widget containing label also. but this widget not visible when I run the program. How can I display this widget called widgetGif
here is part of my code :
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMovie>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
player = new QMediaPlayer(this);
vw = new QVideoWidget (this);
player->setVideoOutput(vw);
this->setCentralWidget(vw); //I think this is the reason
slider = new QSlider(this);
bar = new QProgressBar(this);
slider->setOrientation(Qt::Horizontal);
ui->statusBar->addPermanentWidget(slider);
ui->statusBar->addPermanentWidget(bar);
connect(player,&QMediaPlayer::durationChanged,slider,&QSlider::setMaximum);
connect(player,&QMediaPlayer::positionChanged,slider,&QSlider::setValue);
connect(slider,&QSlider::sliderMoved,player,&QMediaPlayer::setPosition);
connect(player,&QMediaPlayer::durationChanged,bar,&QProgressBar::setMaximum);
connect(player,&QMediaPlayer::positionChanged,bar,&QProgressBar::setValue);
sliderVolumn = new QSlider(this);
sliderVolumn->setOrientation(Qt::Horizontal);
ui->statusBar->addPermanentWidget(sliderVolumn);
connect(sliderVolumn,&QSlider::sliderMoved,player,&QMediaPlayer::setVolume);
QMovie *movie=new QMovie(":/res/icons/giphy.gif");
if (!movie->isValid())
{
// Something went wrong :(
}
ui->labelGif->setMovie(movie);
movie->start();
ui->widgetGif->setVisible(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionOpen_triggered()
{
QString filename= QFileDialog::getOpenFileName(this,"Open Folder","","Open a File(*.*)");
on_actionStop_triggered();
player->setMedia(QUrl::fromLocalFile(filename));
on_actionPlay_triggered();
if(filename.endsWith(".mp3")){
qDebug() << " file is mp3";
}else{
qDebug() << " not is mp3";
}
}
QMainWindow needs a centralWidget. You must use layouts to include your QVideoWidget and also your widgetGif and then set it as centralWidget of the QMainWindow.
In the following example, textEdit would be your QVideoWidget and the object label is like your widgetGif.
We have also two buttons to hide or show label using the method setVisible.
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class QLabel;
class QPushButton;
class QTextEdit;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QWidget *centralWidget;
QLabel *label;
QPushButton *pushButton;
QPushButton *pushButton_2;
QTextEdit *textEdit;
public slots:
void showSlot();
void hideSlot();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Vertical layout
QVBoxLayout *mainLayout = new QVBoxLayout;
// Widgets
centralWidget = new QWidget(this);
label = new QLabel();
pushButton = new QPushButton();
pushButton_2 = new QPushButton();
textEdit = new QTextEdit();
// Title and texts
this->setWindowTitle("MainWindow");
label->setText("TextLabel");
pushButton->setText("Show");
pushButton_2->setText("Hide");
// Add widgets to layout
mainLayout->addWidget(textEdit);
mainLayout->addWidget(label);
mainLayout->addWidget(pushButton);
mainLayout->addWidget(pushButton_2);
centralWidget->setLayout(mainLayout);
// Set the central widget
this->setCentralWidget(centralWidget);
connect(pushButton, SIGNAL (clicked()), this, SLOT (showSlot()));
connect(pushButton_2, SIGNAL (clicked()), this, SLOT (hideSlot()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showSlot()
{
label->setVisible(true);
}
void MainWindow::hideSlot()
{
label->setVisible(false);
}
EDIT:
NOTE this only occurs when the button is in a SUBMENU. (Menu in a menu.) This code works fine only on the parent menu!
Running Qt 5.0.2, on Windows 7. I have a QMenu with a QWidgetAction in it. Inside the QWidgetAction is a QPushButton. I would like to change the background color of the button when the mouse hovers over it.
Here is my code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMenu>
#include <QWidgetAction>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QMenu menu;
QMenu *subMenu = new QMenu("SubMenu text");
QWidgetAction *widgetAction = new QWidgetAction(subMenu);
QPushButton *btn = new QPushButton("test");
btn->setStyleSheet("QPushButton:hover{background-color: #ff0000;}");
widgetAction->setDefaultWidget(btn);
subMenu->addAction(widgetAction);
menu.addMenu(subMenu);
menu.exec();
}
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
However when the cursor hovers over the QPushButton the background color doesn't change. Doesn't matter if I run it in fusion style or not.
What is going on here? Thanks for your time.
This sound like mouseTracking is not enabled on the widget (and/or probably on the parent widget(s)). You can enable it by calling
QWidget::setMouseTracking(bool enable);
Background may not be customized, if you don't change a border style of a button.
How to solve: use some non-default style, for example:
const auto fusion = QStyleFactory::create( "Fusion" );
QApplication::setStyle( fusion );
QPushButton is not designed for perfect handling hover events. For example, hover event will not change a font via stylesheet.
How to solve: use QToolButton instead.
P.S. Don't know, why it's not worked for you. Everything is OK for me...
UPDATE
Just copy-paste it and run:
#include <QApplication>
#include <QWidgetAction>
#include <QMenu>
#include <QPushButton>
#include <QToolButton>
#include <QStyleFactory>
void showMenu()
{
const auto parent = qApp->activeWindow();
auto menu = new QMenu( parent );
auto root = new QMenu( "Root", menu );
menu->addMenu( root );
auto wa = new QWidgetAction( parent );
auto tb = new QToolButton;
tb->setText( "ToolBtn" );
wa->setDefaultWidget( tb );
root->addAction( wa );
menu->exec( QCursor::pos() );
menu->deleteLater();
}
int main(int argc, char *argv[])
{
QApplication a( argc, argv );
const auto fusion = QStyleFactory::create( "Fusion" );
const auto qss =
"QToolButton:!hover{background-color: #00ff00;}"
"QToolButton:hover{background-color: #ff0000;}"
;
QApplication::setStyle( fusion );
qApp->setStyleSheet( qss );
QWidget w;
w.resize( 800, 600 );
auto btn = new QPushButton{ "Test", &w };
QObject::connect( btn, &QPushButton::clicked, &showMenu );
w.show();
return a.exec();
}
I have the following minimal example code given.
main.cpp:
#include <QApplication>
#include "qt.h"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MyDialog mainWin;
mainWin.show();
return app.exec();
}
qt.cpp:
#include <QLabel>
#include "qt.h"
void MyDialog::setupUi()
{
setCentralWidget(new QWidget);
mainLayout = new QVBoxLayout( centralWidget() );
centralWidget()->setLayout(mainLayout);
// show the add new effect channel button
QPushButton* newKnobBtn = new QPushButton("new", this );
connect( newKnobBtn, SIGNAL(clicked()), this, SLOT(addNewKnob()));
mainLayout->addWidget( newKnobBtn, 0, Qt::AlignRight );
containerWidget = new QWidget(this);
scrollArea = new QScrollArea(containerWidget);
mainLayout->addWidget(containerWidget);
scrollLayout = new QVBoxLayout(scrollArea);
scrollArea->setLayout(scrollLayout);
/*
QSizePolicy pol;
pol.setVerticalPolicy(QSizePolicy::Expanding);
setSizePolicy(pol);
*/
addNewKnob(); // to fit size initially
}
void MyDialog::addNewKnob()
{
scrollLayout->addWidget(new QLabel("Hello World", this));
/*
containerWidget->adjustSize();
adjustSize();
*/
}
qt.h:
#include <QMainWindow>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QPushButton>
class MyDialog : public QMainWindow
{
Q_OBJECT
private slots:
void addNewKnob();
private:
void setupUi();
QVBoxLayout* mainLayout;
QScrollArea* scrollArea;
QVBoxLayout* scrollLayout;
QWidget* containerWidget;
public:
MyDialog( ) { setupUi(); }
};
Compiling: Put all in one directory, type
qmake -project && qmake && make
I have the adjustSize() solution from here, but it does not work: (link). Everything I commented out was things I tried but did not help.
How do I make containerWidget and scrollLayout grow correctly, when a new Label is being added to scrollLayout?
Here's a simplified version that works for me:
qt.cpp:
#include <QLabel>
#include <QPushButton>
#include <QScrollArea>
#include "qt.h"
MyDialog::MyDialog()
{
QWidget * mainWidget = new QWidget;
QBoxLayout * mainLayout = new QVBoxLayout(mainWidget);
setCentralWidget(mainWidget);
// show the add new effect channel button
QPushButton* newKnobBtn = new QPushButton("new");
connect( newKnobBtn, SIGNAL(clicked()), this, SLOT(addNewKnob()));
mainLayout->addWidget( newKnobBtn, 0, Qt::AlignRight );
QScrollArea * scrollArea = new QScrollArea;
scrollArea->setWidgetResizable(true);
mainLayout->addWidget(scrollArea);
QWidget * labelsWidget = new QWidget;
labelsLayout = new QVBoxLayout(labelsWidget);
scrollArea->setWidget(labelsWidget);
addNewKnob(); // to fit size initially
}
void MyDialog::addNewKnob()
{
labelsLayout->addWidget(new QLabel("Hello World"));
}
qt.h:
#include <QMainWindow>
#include <QBoxLayout>
class MyDialog : public QMainWindow
{
Q_OBJECT
public:
MyDialog( );
private slots:
void addNewKnob();
private:
QBoxLayout * labelsLayout;
};
You have containerWidget that contain only one QScrollArea. I don't know why do you need this. But if you need this for some reason, you need to add a layout to this widget in order to make layouts work. Also do not create a layout for QScrollArea. It already have internally implemented layout. You should add scrollLayout to the scroll area's viewport() widget instead.
When you construct a layout and pass a widget to its constructor, the layout is automatically assigned to the passed widget. You should not call setLayout after that. This action will take no effect and produce console warning.
I am a QT newbie and trying to play around with Apps. I have just coded a very trivial App with some buttons. The main idea is to have a small "logo" in my App. LAter I would like to add some background image as well.
I have coded from an example App with a grid layout within which is a QBoxLayout which groups my buttons.
As you can see in my code, I have tried adding the Logo everywhere. When I added it in main.cpp, I have two views one showing buttons and the other my logo. Of course I do not want this. So I tried adding it in mainwindow.cpp but in this case, I don't see my Logo appearing anywhere at all :(
Please advise.
Here is the code:
main.cpp:
#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window window;
window.show();
/*
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsPixmapItem item(QPixmap("/home/marc/Desktop/Niranjana/Images/logo.9.png"));
scene.addItem(&item);
view.show();
*/
return a.exec();
}
mainwindow.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
#include <QRadioButton>
class QGroupBox;
class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = 0);
void onCheck_remote(int flag);
void onCheck_local(int flag);
private:
QRadioButton *button_local;
QRadioButton *button_remote;
QGroupBox *createPushButtonGroup();
};
#endif
mainwindow.cpp
#include <QtGui>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include "mainwindow.h"
Window::Window(QWidget *parent)
: QWidget(parent)
{
QGridLayout *grid = new QGridLayout;
QGraphicsScene scene;
QGraphicsPixmapItem item(QPixmap("/home/test/logo.png"));
QGraphicsView view(&scene);
scene.addItem(&item);
view.show();
grid->addWidget(view.viewport(), 1, 1);
grid->addWidget(createPushButtonGroup(), 2, 1);
setLayout(grid);
setWindowTitle(tr("My App"));
resize(480, 420);
}
QGroupBox *Window::createPushButtonGroup()
{
QGroupBox *groupBox = new QGroupBox();
/*
QGraphicsScene scene;
QGraphicsPixmapItem item(QPixmap("/home/marc/Desktop/Niranjana/Images/logo.9.png"));
QGraphicsView view(&scene);
scene.addItem(&item);
scene.setBackgroundBrush(Qt::white);
view.show();
*/
QPushButton *button1 = new QPushButton(tr("&Start"));
QPushButton *button2 = new QPushButton(tr("&Stop"));
button_local = new QRadioButton(tr("&with power"));
button_remote = new QRadioButton(tr("without power"));
button_local->setChecked(1);
QVBoxLayout *vbox = new QVBoxLayout;
// vbox->addSpacing(10);
// vbox->addWidget(view.viewport());
//vbox->addSpacing(10);
vbox->addWidget(button1);
vbox->addSpacing(10);
vbox->addWidget(button2);
vbox->addSpacing(50);
vbox->addWidget(button_local);
vbox->addWidget(button_remote);
vbox->addStretch(1);
groupBox->setLayout(vbox);
return groupBox;
}
You should
Make your scene, view, item pointer members of your window class
Instantiate them in your Window ctor
do grid->addWidget(view, 1, 1);
Otherwise, all the items instantiated on the stack in the ctor will get deleted when exiting.