In my Qt program, I want to catch the signal of one of my checkbox to know if it's checked or not. I did it :
#include <iostream>
#include <QVBoxLayout>
#include <QtGui>
#include "Window.h"
Window::Window() : QWidget()
{
setFixedSize(400, 800);
m_bouton = new QPushButton("Module 1");
m_bouton->setCursor(Qt::PointingHandCursor);
m_bouton2 = new QPushButton("Module 2");
m_bouton2->setCursor(Qt::PointingHandCursor);
m_bouton3 = new QPushButton("Module 3");
m_bouton3->setCursor(Qt::PointingHandCursor);
m_bouton4 = new QPushButton("Module 4");
m_bouton4->setCursor(Qt::PointingHandCursor);
m_check4 = new QCheckBox(this);
m_check4->move(300, 50);
m_check4->setChecked(true);
m_check3 = new QCheckBox(this);
m_check3->move(200, 50);
m_check3->setChecked(true);
m_check2 = new QCheckBox(this);
m_check2->move(100, 50);
m_check2->setChecked(true);
m_check1 = new QCheckBox(this);
m_check1->move(0, 50);
m_check1->setChecked(true);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(m_bouton);
layout->addWidget(m_bouton2);
layout->addWidget(m_bouton3);
layout->addWidget(m_bouton4);
this->setLayout(layout);
this->setStyleSheet("border: 1px solid black; border-radius: 10px;");
this->setWindowOpacity(0.5);
QWidget::setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
QWidget::setWindowTitle("Monitor Core");
QObject::connect(m_bouton4, SIGNAL(clicked()), this, SLOT(SizeCHange()));
QObject::connect(m_check4, SIGNAL(clicked()), this, SLOT(SizeCHange()));
}
void Window::SizeCHange()
{
setFixedSize(400, 800 - 200);
m_bouton4->setVisible(false);
}
and this is my .h :
#ifndef _WINDOW_H_
#define _WINDOW_H_
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QCheckBox>
class Window : public QWidget
{
Q_OBJECT
public:
Window();
public slots:
void SizeCHange();
private:
QPushButton *m_bouton;
QPushButton *m_bouton2;
QPushButton *m_bouton3;
QPushButton *m_bouton4;
QCheckBox *m_check1;
QCheckBox *m_check2;
QCheckBox *m_check3;
QCheckBox *m_check4;
};
#endif
This is working but just one time. I want to know if it's check or not, then I will be able to resize my window and make something invisible as I want.
You simply need to use a bool parameter, which indicates the state of the checkbox:
public slots:
void SizeCHange(bool checked); //using bool parameter
//...
QObject::connect(m_check4, SIGNAL(clicked(bool)), this, SLOT(SizeCHange(bool)));
//...
void Window::SizeCHange(bool checked)
{
if(checked)
{
setFixedSize(400, 800 - 200);
}
else
{
// removing fixed size
setMinimumSize(QSize(0, 0));
setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
}
m_bouton4->setVisible(checked);
}
The docs for a signal clicked()
Related
I have an application which shows some images in a grid and rest of the widgets in their respective positions. Something like this
Drawing inspiration from this i managed to solve keeping the aspect ratio of an image while resizing.
What are the issues:
The QLabel widgets(image widgets) overlap if QMainWindow is shrinked. Check the image below
The whole application is apparently not suited for different screens. Running this application on a laptop, layout is completely messed up.
What have i done:
Here is the MVCE code i have created
//ImageWidget.h
#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H
#include <QLabel>
#include <QResizeEvent>
#include <QWidget>
class ImageWidget : public QLabel
{
Q_OBJECT
public:
explicit ImageWidget(QWidget* parent = nullptr);
virtual QSize sizeHint() const;
QPixmap scaledPixmap() const;
virtual int widthForHeight(int height) const;
public slots:
void setPixmap ( const QPixmap& p);
void resizeEvent(QResizeEvent* ev);
private:
QPixmap pix;
};
#endif // IMAGEWIDGET_H
ImageWidget.cpp
#include "imagewidget.h"
ImageWidget::ImageWidget(QWidget* parent) :
QLabel(parent)
{
setStyleSheet("QLabel{margin-left: 10px; border-radius: 25px; background: white; color: #4A0C46;}");
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy.setWidthForHeight(true);
setSizePolicy(sizePolicy);
setMinimumSize(sizeHint());
}
void ImageWidget::setPixmap (const QPixmap& p)
{
pix = p;
QLabel::setPixmap(scaledPixmap());
}
/* virtual */ int ImageWidget::widthForHeight(int height) const
{
return pix.isNull() ? height * pix.height() / pix.width() : height;
}
QSize ImageWidget::sizeHint() const
{
if(pix.width() != 0)
{
int h = this->height();
return QSize(widthForHeight(h), h);
}
else
{
return QSize(300, 300);
}
}
QPixmap ImageWidget::scaledPixmap() const
{
auto scaled = pix.scaled(this->size() * devicePixelRatioF(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
scaled.setDevicePixelRatio(devicePixelRatioF());
return scaled;
}
void ImageWidget::resizeEvent(QResizeEvent* )
{
if (!pix.isNull())
{
QLabel::setPixmap(scaledPixmap());
}
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QTableWidget>
#include "imagewidget.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
virtual void resizeEvent(QResizeEvent* event) override;
private:
Ui::MainWindow *ui;
ImageWidget* lbl1;
ImageWidget* lbl2;
ImageWidget* lbl3;
ImageWidget* lbl4;
QPushButton* btn1;
QPushButton* btn2;
QPushButton* btn3;
QPushButton* btn4;
QTableWidget* tableWidget;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVBoxLayout>
#include <QTabWidget>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QTabBar>
MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout* mainLayout = new QVBoxLayout;
QVBoxLayout* tabLay = new QVBoxLayout;
QHBoxLayout* buttonLay = new QHBoxLayout;
QGridLayout* gridLay = new QGridLayout;
QHBoxLayout* dockLay = new QHBoxLayout;
btn1 = new QPushButton(this);
btn1->setText("Button1");
btn2 = new QPushButton(this);
btn2->setText("Button2");
btn3 = new QPushButton(this);
btn3->setText("Button3");
btn4 = new QPushButton(this);
btn4->setText("Button4");
QTabWidget* tabView = new QTabWidget(this);
tabView->addTab(new QWidget(), "Table");
tabView->setMinimumSize(500, 300);
tabView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
tableWidget = new QTableWidget(this);
tableWidget->setFixedHeight(200);
lbl1 = new ImageWidget(this);
lbl2 = new ImageWidget(this);
lbl3 = new ImageWidget(this);
lbl4 = new ImageWidget(this);
QPixmap lbl1Pix("1.png");
QPixmap lbl2Pix("2.png");
QPixmap lbl3Pix("3.png");
QPixmap lbl4Pix("4.png");
lbl1->setPixmap(lbl1Pix);
lbl1->show();
lbl2->setPixmap(lbl2Pix);
lbl2->show();
lbl3->setPixmap(lbl3Pix);
lbl3->show();
lbl4->setPixmap(lbl4Pix);
lbl4->show();
buttonLay->addWidget(btn1);
buttonLay->addWidget(btn2);
buttonLay->addWidget(btn3);
buttonLay->addWidget(btn4);
tabLay->addWidget(tabView);
gridLay->addWidget(lbl1, 0, 0);
gridLay->addWidget(lbl2, 0, 1);
gridLay->addWidget(lbl3, 1, 0);
gridLay->addWidget(lbl4, 1, 1);
dockLay->addLayout(gridLay);
dockLay->addLayout(tabLay);
mainLayout->addLayout(dockLay);
mainLayout->addLayout(buttonLay);
mainLayout->addWidget(tableWidget);
centralWidget()->setLayout(mainLayout);
setMinimumSize(200,200);
show();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::resizeEvent(QResizeEvent * /*event*/)
{
// get label dimensions
int h = lbl1->height();
int w = lbl1->widthForHeight(h);
lbl1->setFixedWidth(w);
lbl2->setFixedWidth(w);
lbl3->setFixedWidth(w);
lbl4->setFixedWidth(w);
}
Main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
What do i want:
Set a minimum size to the whole application so that the imagewidgets do not overlap.
Make the whole app work on any PC or laptop screen with different resolutions.
The imagewidgets should take up available space while keeping the aspect ratio of the images and the QTabWidget on the right should have a fixed size.
Maybe there is an easy solution but i am bit confused with Qt Layout management system.
EDIT1: Added the image with overlapping widgets
Here is what I think is happening. When you set the pixmap like here:
QLabel::setPixmap(scaledPixmap());
The label will set the size of the images as the minimum size. And from that point on the label can not be resized any smaller.
The solution I have found around this is to set the following resize flags for the QLabel in the constructor:
QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
setSizePolicy(sizePolicy);
This way the QLabel will be resizable at all times. Or you might have to adapt the minimum width.
I am not sure if that is even it, but maybe it is a good start. Let me know what you make of this.
I have a QListWidget that is in a QGridLayout in my constructor of the Draw class.QGridLAyout contains other elements.
Draw::Draw(QWidget *parent):QDialog(parent){
gridlayout=new QGridLayout;
gridlayout->addLayout(hbox,0,0);
gridlayout->addLayout(hbox1,1,0);
gridlayout->addLayout(hbox2,2,0);
gridlayout->addWidget(listWidget,3,0);
gridlayout->addLayout(hbox4,4,0);
this->setLayout(gridlayout);
}
When clicking on a QPushButton. I'm calling a slot that filled the QListWidget.
//SLOT
void Draw::fillListWidget(){
//item is QListWidgetItem
item=new QListWidgetItem;
item->setSizeHint(QSize(0,50));
listWidget->addItem(item);
//WidgetfillListWidget is an other class with parameters for the QListWidget
listWidget->setItemWidget(item,new WidgetfillListWidget(label1,path));
}
In my other class I build the new QWidget to fill the QlistWidget. The QListWidget contains a label, a string and a QPushButton.
WidgetfillListWidget::WidgetfillListWidget(QString label, QString p){
instanceDraw=new Draw(this);
QString name = label;
QString path = p;
name1=new QLabel(name,this);
path1=new QLineEdit(path,this);
remove=new QPushButton("remove",this);
hboxlist=new QHBoxLayout;
hboxlist->addWidget(name1);
hboxlist->addWidget(path1);
hboxlist->addWidget(remove);
setLayout(hboxlist);
connect(remove,SIGNAL(clicked()),instanceDraw,SLOT(removeItem()));
}
In the Draw class I have the slot that has to delete an item but it does not work
void Draw::removeItem(){
listWidget->takeItem(listWidget->row(item));
}
Deleting the item does not work. I think it comes from my Draw object in the connect. But I do not understand how to solve the problem. Does someone have an idea?
The problem is because the Draw created in WidgetfillListWidget is different from the original Draw, they are 2 different objects.
In this case the solution is to create a clicked signal in WidgetfillListWidget that is issued when the QPushButton is pressed.
Then that signal is connected to the removeItem() method. In it we must obtain the item, but that is not simple, one way to do it is through the geometric position as I show below:
widgetfilllistwidget.h
#ifndef WIDGETFILLLISTWIDGET_H
#define WIDGETFILLLISTWIDGET_H
#include <QWidget>
class QLabel;
class QPushButton;
class QHBoxLayout;
class QLineEdit;
class WidgetfillListWidget : public QWidget
{
Q_OBJECT
public:
explicit WidgetfillListWidget(const QString & name, const QString &path, QWidget *parent = nullptr);
signals:
void clicked();
private:
QLabel *lname;
QLineEdit *lpath;
QPushButton *premove;
QHBoxLayout *hboxlist;
};
#endif // WIDGETFILLLISTWIDGET_H
widgetfilllistwidget.cpp
#include "widgetfilllistwidget.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
WidgetfillListWidget::WidgetfillListWidget(const QString &name, const QString & path, QWidget *parent) : QWidget(parent)
{
lname=new QLabel(name);
lpath=new QLineEdit(path);
premove=new QPushButton("remove");
hboxlist=new QHBoxLayout(this);
hboxlist->addWidget(lname);
hboxlist->addWidget(lpath);
hboxlist->addWidget(premove);
connect(premove, &QPushButton::clicked, this, &WidgetfillListWidget::clicked);
}
draw.h
#ifndef DRAW_H
#define DRAW_H
#include <QDialog>
class QGridLayout;
class QListWidget;
class QPushButton;
class Draw : public QDialog
{
Q_OBJECT
public:
Draw(QWidget *parent = 0);
~Draw();
private:
void fillListWidget();
void removeItem();
QGridLayout *gridlayout;
QListWidget *listWidget;
QPushButton *button;
};
#endif // DRAW_H
draw.cpp
#include "draw.h"
#include "widgetfilllistwidget.h"
#include <QGridLayout>
#include <QListWidget>
#include <QPushButton>
Draw::Draw(QWidget *parent)
: QDialog(parent)
{
button = new QPushButton("Press Me");
listWidget = new QListWidget;
gridlayout=new QGridLayout(this);
gridlayout->addWidget(listWidget, 0, 0);
gridlayout->addWidget(button, 1, 0);
connect(button, &QPushButton::clicked, this, &Draw::fillListWidget);
}
void Draw::fillListWidget()
{
QListWidgetItem *item=new QListWidgetItem;
item->setSizeHint(QSize(0,50));
listWidget->addItem(item);
//WidgetfillListWidget is an other class with parameters for the QListWidget
QString label = "label1";
QString path = "label2";
WidgetfillListWidget *widget = new WidgetfillListWidget(label,path);
listWidget->setItemWidget(item, widget);
connect(widget, &WidgetfillListWidget::clicked, this, &Draw::removeItem);
}
void Draw::removeItem()
{
WidgetfillListWidget *widget = qobject_cast<WidgetfillListWidget *>(sender());
if(widget){
QPoint gp = widget->mapToGlobal(QPoint());
QPoint p = listWidget->viewport()->mapFromGlobal(gp);
QListWidgetItem *item = listWidget->itemAt(p);
item = listWidget->takeItem(listWidget->row(item));
delete item;
}
}
Draw::~Draw()
{
}
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 considering transitioning between menu screens in a game by using QStateMachine. However, I'm unsure how to kick off some code (e.g. show() a QWidget) upon a transition between states occurring. I can do it quite easily with plain old signals (see commented out code), but I figure that I could probably do some fancy animation upon switching screens using transitions.
Here's my code:
Edit: updated as per Koying's suggestion.
ApplicationWindow.h:
#include <QtGui>
#include <QStateMachine>
#include "MainMenu.h"
#include "LoadGameMenu.h"
class ApplicationWindow : public QMainWindow
{
Q_OBJECT
public:
ApplicationWindow();
private slots:
void mainMenuButtonClicked();
void loadGameMenuButtonClicked();
private:
MainMenu* mainMenu;
LoadGameMenu* loadGameMenu;
QStateMachine stateMachine;
QStackedWidget* stack;
};
ApplicationWindow.cpp:
ApplicationWindow::ApplicationWindow()
{
resize(800, 600);
stack = new QStackedWidget(this);
mainMenu = new MainMenu();
setCentralWidget(mainMenu);
loadGameMenu = new LoadGameMenu();
QState* mainMenuState = new QState();
QState* loadGameMenuState = new QState();
QAbstractTransition* loadTransition = mainMenuState->addTransition(
mainMenu, SIGNAL(loadGameClicked()), loadGameMenuState);
connect(loadTransition, SIGNAL(triggered()), this, SLOT(loadGameMenuButtonClicked()));
QAbstractTransition* mainMenuTransition = loadGameMenuState->addTransition(
loadGameMenu, SIGNAL(backToMainMenuClicked()), mainMenuState);
connect(mainMenuTransition, SIGNAL(triggered()), this, SLOT(mainMenuButtonClicked()));
stateMachine.addState(mainMenuState);
stateMachine.addState(loadGameMenuState);
stateMachine.setInitialState(mainMenuState);
stateMachine.start();
}
void ApplicationWindow::mainMenuButtonClicked()
{
setCentralWidget(mainMenu);
}
void ApplicationWindow::loadGameMenuButtonClicked()
{
setCentralWidget(loadGameMenu);
}
LoadGameMenu.h:
#include <QtGui>
class LoadGameMenu : public QWidget
{
Q_OBJECT
public:
LoadGameMenu();
signals:
void backToMainMenuClicked();
private:
QPushButton* loadGameButton;
QPushButton* backToMainMenuButton;
};
LoadGameMenu.cpp:
#include "LoadGameMenu.h"
LoadGameMenu::LoadGameMenu()
{
loadGameButton = new QPushButton(tr("Load"));
backToMainMenuButton = new QPushButton(tr("Main Menu"));
QObject::connect(backToMainMenuButton, SIGNAL(clicked()),
this, SIGNAL(backToMainMenuClicked()));
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(loadGameButton);
layout->addWidget(backToMainMenuButton);
layout->setContentsMargins(300, 400, 300, 200);
setLayout(layout);
}
MainMenu.h:
#include <QtGui>
class MainMenu : public QWidget
{
Q_OBJECT
public:
MainMenu();
signals:
void newGameClicked();
void loadGameClicked();
private slots:
void exit();
private:
QPushButton* newGameButton;
QPushButton* loadGameButton;
QPushButton* exitGameButton;
QMenu* fileMenu;
};
MainMenu.cpp:
#include "MainMenu.h"
MainMenu::MainMenu()
{
newGameButton = new QPushButton(tr("New Game"), this);
loadGameButton = new QPushButton(tr("Load Game"));
exitGameButton = new QPushButton(tr("Exit"));
QObject::connect(newGameButton, SIGNAL(clicked()), this, SIGNAL(newGameClicked()));
QObject::connect(loadGameButton, SIGNAL(clicked()), this, SIGNAL(loadGameClicked()));
QObject::connect(exitGameButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(newGameButton);
layout->addWidget(loadGameButton);
layout->addWidget(exitGameButton);
layout->setContentsMargins(300, 200, 300, 200);
setLayout(layout);
}
void MainMenu::exit()
{
if( QMessageBox::question(
this,
tr("Exit?"),
tr("Do you really want to exit the game?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No
) == QMessageBox::Yes
)
{
qApp->quit();
}
}
main.cpp:
#include <QtGui>
#include "ApplicationWindow.h"
int main(int argv, char **args)
{
QApplication app(argv, args);
ApplicationWindow window;
window.show();
return app.exec();
}
So, how do I trigger some behaviour or action when a transition occurs?
Cheers.
To actually do something on a state transition, you have to connect to the triggered() signal of the transition, e.g.
QAbstractTransition* trMainLoad = mainMenuState->addTransition(mainMenu, SIGNAL(loadGameClicked()), loadGameMenuState);
connect(trMainLoad , SIGNAL(triggered()), SLOT(...));
Basically, I have multiple widgets I'm trying to switch between... and the default is a QTabWidget. Aside from some modification, the two examples (QStackedWidget and QTabsExapmle) are just mingled together. I can't get the "connect" portion to work (get an error: no matching function for call to QTabsExample::connect), and nothing displays on screen unless stackedWidget->addWidget(tabWidget) is the first in the list (and even then, I only see the view in the upper left hand corner).
QTabsExample.h
#ifndef QTABSEXAMPLE_H
#define QTABSEXAMPLE_H
#include <QtGui/QMainWindow>
#include <QtGui/QScrollArea>
#include <QtGui/QFrame>
#include <QtGui/QVBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QGroupBox>
#include <QtGui/QFormLayout>
#include <QtGui/QMessageBox>
#include <QtCore/QPointer>
#include <QtCore/QFile>
#include <QtCore/QIODevice>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtXml/QXmlStreamReader>
#include <QtDebug>
#include <QBool>
#include <QSignalMapper>
#include <QStackedLayout>
class QTabsExample: public QMainWindow {
Q_OBJECT
public:
QTabsExample(QWidget *parent = 0);
~QTabsExample();
private:
void buildTabMenuBar(int index);
public slots:
void activeTabChanged(int index);
void setCurrentIndex(int);
signals:
void activated(int);
private:
QTabWidget* tabWidget;
QWidget* customWidget1;
QWidget* customWidget2;
QWidget* customWidget3;
};
// ---------------------------------------------------------------------------
// QMyWidget - Tab1
//
class QMyWidget: public QWidget {
Q_OBJECT
public:
QMyWidget(QWidget *parent = 0);
~QMyWidget();
public slots:
void runOnTabSelect();
private:
QPointer<QVBoxLayout> _layout;
};
// ---------------------------------------------------------------------------
// QMyWidget2 - Tab2
//
class QMyWidget2: public QWidget {
Q_OBJECT
public:
QMyWidget2(QWidget *parent = 0);
~QMyWidget2();
public slots:
void runOnTabSelect();
};
// ---------------------------------------------------------------------------
// QMyWidget3 - Tab3
//
class QMyWidget3: public QWidget {
Q_OBJECT
public:
QMyWidget3(QWidget *parent = 0);
~QMyWidget3();
public slots:
void runOnTabSelect();
private:
QPointer<QVBoxLayout> _layout;
};
#endif // QTABSEXAMPLE_H
QTabsExample.cpp
#include <QtGui>
#include <QApplication>
#include "QTabsExample.h"
QTabsExample::QTabsExample(QWidget *parent) : QMainWindow(parent) {
setContextMenuPolicy(Qt::NoContextMenu);
this->setWindowTitle("Main Window, I think");
QStackedLayout *stackedLayout = new QStackedLayout;
//create tab widget
QTabWidget *tabWidget = new QTabWidget();
tabWidget->setContextMenuPolicy(Qt::NoContextMenu);
QObject::connect(tabWidget, SIGNAL(currentChanged(int)),this, SLOT(activeTabChanged(int)));
QMyWidget* widget1 = new QMyWidget();
tabWidget->addTab(widget1, "Tab1");
QMyWidget2* widget2 = new QMyWidget2();
tabWidget->addTab(widget2, "Tab2");
QMyWidget3* widget3 = new QMyWidget3();
tabWidget->addTab(widget3, "Tab3");
//set programatically
tabWidget->setStyleSheet("QTabBar::tab { height: 70px; width: 80px; font-size: 15px;}");
//create other widgets
QWidget* customWidget1 = new QWidget;
QWidget* customWidget2 = new QWidget;
QWidget* customWidget3 = new QWidget;
//add layouts to widgets
customWidget1->setContextMenuPolicy(Qt::NoContextMenu);
customWidget2->setContextMenuPolicy(Qt::NoContextMenu);
customWidget3->setContextMenuPolicy(Qt::NoContextMenu);
customWidget1->setWindowTitle("Widget 1");
customWidget2->setWindowTitle("Widget 2");
customWidget3->setWindowTitle("Widget 3");
//insert content to make sure it's viewable
QPalette palette;
palette.setBrush(this->backgroundRole(), QBrush(QImage("c://default.png")));
customWidget1->setPalette(palette);
palette.setBrush(this->backgroundRole(), QBrush(QImage("c://default2.png")));
customWidget2->setPalette(palette);
palette.setBrush(this->backgroundRole(), QBrush(QImage("c://default3.png")));
customWidget3->setPalette(palette);
//add widgets to stack
stackedLayout->addWidget(tabWidget);
stackedLayout->addWidget(customWidget1);
stackedLayout->addWidget(customWidget2);
stackedLayout->addWidget(customWidget3);
QComboBox *pageComboBox = new QComboBox;
pageComboBox->addItem(tr("Tab Page"));
pageComboBox->addItem(tr("page 2"));
pageComboBox->addItem(tr("page 3"));
pageComboBox->addItem(tr("page 4"));
connect(pageComboBox, SIGNAL(activated(int))), stackedLayout, SLOT(setCurrentIndex(int));
QVBoxLayout *_layout = new QVBoxLayout;
_layout->addWidget(pageComboBox);
_layout->addLayout(stackedLayout);
setLayout(_layout);
//setCentralWidget(tabWidget);
#ifdef Q_OS_SYMBIAN
QWidgetList widgets = QApplication::allWidgets();
QWidget* w = 0;
foreach(w,widgets) {
w->setContextMenuPolicy(Qt::NoContextMenu);
}
#endif
}
QTabsExample::~QTabsExample(){
}
void QTabsExample::activeTabChanged(int index) {
buildTabMenuBar(index);
}
void QTabsExample::buildTabMenuBar(int index) {
QMenuBar* menubar = menuBar();
menubar->clear();
switch (index) {
case 0:
{
menubar->addAction("", tabWidget->widget(index), SLOT(runOnTabSelect()));
break;
}
case 1:
{
menubar->addAction("", tabWidget->widget(index), SLOT(runOnTabSelect()));
break;
}
case 2:
{
menubar->addAction("", tabWidget->widget(index), SLOT(runOnTabSelect()));
break;
}
default:
{
break;
}
};
}
//tab1
QMyWidget::QMyWidget(QWidget *parent) : QWidget(parent) {
setContextMenuPolicy(Qt::NoContextMenu);
QVBoxLayout* _layout = new QVBoxLayout(this);
//buttons get created
this->setLayout(_layout);
}
QMyWidget::~QMyWidget() {
}
void QMyWidget::runOnTabSelect() {
}
//tab2
QMyWidget2::QMyWidget2(QWidget *parent) : QWidget(parent) {
setContextMenuPolicy(Qt::NoContextMenu);
QVBoxLayout* _layout = new QVBoxLayout(this);
//buttons get created
this->setLayout(_layout);
}
QMyWidget2::~QMyWidget2() {
}
void QMyWidget2::runOnTabSelect() {
}
//tab3
QMyWidget3::QMyWidget3(QWidget *parent) : QWidget(parent) {
setContextMenuPolicy(Qt::NoContextMenu);
QVBoxLayout* _layout = new QVBoxLayout(this);
//buttons get created
this->setLayout(_layout);
}
QMyWidget3::~QMyWidget3() {
}
void QMyWidget3::runOnTabSelect() {
}
main.cpp
#include "QTabsExample.h""
#include <QtGui>
#include <QApplication>
#include <QtGui/QApplication>
#include <QPixmap>
#include <QWidget>
#include <QMainWindow>
#include <QSplashScreen>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTabsExample w;
w.showMaximized();
return a.exec();
}
Well for starters you need to uncomment //QTabsExample w; in main.cpp, but I guess, that is just a relict from experimenting...
Also, what do you mean by "nothing displays on screen."?
Do you mean, that an empty window pops up? Or does no window at all open? Or does the screen turn black?
Have you eliminated the possibility that the "app.css" file might be corrupt?
Have you tried deleting the Makefiles and moc_* files?
EDIT:
I tried to simplify the constructor of QTabsExample
#include <QtGui>
#include <QApplication>
#include "QTabsExample.h"
QTabsExample::QTabsExample(QWidget *parent) : QMainWindow(parent) {
setContextMenuPolicy(Qt::NoContextMenu);
this->setWindowTitle("Main Window, I think");
//create tab widget
QTabWidget *tabWidget = new QTabWidget();
tabWidget->setContextMenuPolicy(Qt::NoContextMenu);
//QObject::connect(tabWidget, SIGNAL(currentChanged(int)),this, SLOT(activeTabChanged(int))); // I have no experience with mobile developement
// can you manipulate the menubar on a mobile device?
QMyWidget* widget1 = new QLabel(tr("Widget1")); // simplification
tabWidget->addTab(widget1, "Tab1");
QMyWidget2* widget2 = new QLabel(tr("Widget2"));
tabWidget->addTab(widget2, "Tab2");
QMyWidget3* widget3 = new QLabel(tr("Widget3"));
tabWidget->addTab(widget3, "Tab3");
//set programatically
tabWidget->setStyleSheet("QTabBar::tab { height: 70px; width: 80px; font-size: 15px;}");
//create other widgets
QWidget* customWidget1 = new QLabel(tr("Hello1")); // simplification
QWidget* customWidget2 = new QLabel(tr("Hello2"));
QWidget* customWidget3 = new QLabel(tr("Hello3"));
// create stacked layout (closer to where it is actually used)
QStackedLayout *stackedLayout = new QStackedLayout;
//add widgets to stack
stackedLayout->addWidget(tabWidget);
stackedLayout->addWidget(customWidget1);
stackedLayout->addWidget(customWidget2);
stackedLayout->addWidget(customWidget3);
QComboBox *pageComboBox = new QComboBox;
pageComboBox->addItem(tr("Tab Page"));
pageComboBox->addItem(tr("page 2"));
pageComboBox->addItem(tr("page 3"));
pageComboBox->addItem(tr("page 4"));
connect(pageComboBox, SIGNAL(activated(int))), stackedLayout, SLOT(setCurrentIndex(int));
QVBoxLayout *_layout = new QVBoxLayout;
_layout->addWidget(pageComboBox);
_layout->addLayout(stackedLayout);
setLayout(_layout);
//setCentralWidget(tabWidget);
#ifdef Q_OS_SYMBIAN
QWidgetList widgets = QApplication::allWidgets();
QWidget* w = 0;
foreach(w,widgets) {
w->setContextMenuPolicy(Qt::NoContextMenu);
}
#endif
}
Expected behaviour:
a combo box on the top with choices: "Tab Page", "page 2", ...
below a QTabWidget witht the tabs: "Tab1", "Tab2", "Tab3"
Tab1 should be displayed with a QLabel, which says "Widget1"
when you select another tab, the label should say "WidgetX" // depending on your choice
when you select another widget from the combo box you should see "HelloX" // depending on your choice