QTabwidget click tab event C++ - c++

I am new in QT 4 C++ .I have QT 4 form with QTabwidget like in th picture below.
enter image description here
I want to disply on console the string "aa" by selecting tab on clicking it.
Here is my newForm.h
#ifndef _NEWFORM_H
#define _NEWFORM_H
#include "qwidget.h"
#include "ui_newForm.h"
class newForm : public QDialog {
Q_OBJECT
public:
newForm();
virtual ~newForm();
private:
Ui::newForm widget;
};
#endif /* _NEWFORM_H */
_________________________________________________________________________________________
Here is my main.cpp
#include <QApplication>
#include "newForm.h"
int main(int argc, char *argv[]) {
// initialize resources, if needed
// Q_INIT_RESOURCE(resfile);
QApplication app(argc, argv);
newForm *a = new newForm();
a->show();
// create and show your widgets here
return app.exec();
}
Here is my newForm.cpp
#include "newForm.h"
#include <iostream>
#include <QDebug>
newForm::newForm() {
connect(widget.tabWidget, SIGNAL(stateChanged()), this, SLOT(onTabChanged(int)));
widget.setupUi(this);
}
newForm::~newForm() {
}
void newForm::onTabChanged(int ){
qDebug()<<"aa"<<"\n";
}
On selecting new tab it is not displaying "aa"?How to qDebug() "aa" on console?

First of all, why are you using Qt 4 in 2022?
Next thing use currentIndexChanged(int) istead of stateChanged().
Did you also noticed that stateChanged() doesnt pass an interger which is needed for onTabChanged(int).
You also connected widget.tabWidget which isn't initilized yet.
This code might work:
newForm.h
#ifndef _NEWFORM_H
#define _NEWFORM_H
#include "qwidget.h"
namespace Ui { class newForm; };
class newForm : public QDialog {
Q_OBJECT
public:
newForm();
~newForm();
private:
Ui::newForm *widget;
};
#endif /* _NEWFORM_H */
newForm.cpp
#include "newForm.h"
#include "ui_newForm.h"
#include <QDebug>
newForm::newForm()
: widget(new Ui::newForm)
{
widget->setupUi(this);
connect(widget->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(onTabChanged(int)));
}
void newForm::onTabChanged(int ){
qDebug() << "aa";
}
newForm::~newForm() {
delete widget;
}
main.cpp
#include <QApplication>
#include "newForm.h"
int main(int argc, char *argv[]) {
// initialize resources, if needed
// Q_INIT_RESOURCE(resfile);
QApplication app(argc, argv);
newForm a;
a.show();
// create and show your widgets here
return app.exec();
}

Related

how to use scene object of main file in other file?

I tried to make tictactoe game using Qt and Qgraphicsview but when I draw x on board using Graphicstextitem in mousePressEvent , X does not appear. how fix that ?
I think the problem is that scene of textitem Different from scene of main file but I do not know how fix that.
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Game *gm = new Game;
Game *rect1=new Game;
gm->scenc->setSceneRect(0,0,800,600);
rect1->setRect(160,100,150,150);
gm->scenc->addItem(rect1);
gm->view->setScene(gm->scenc);
gm->view->show();
return a.exec();
}
in game.cpp:
#include <game.h>
Game::Game()
{
scenc= new QGraphicsScene;
view = new QGraphicsView;
text= new QGraphicsTextItem;
}
void Game::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->buttons() == Qt::LeftButton )
{
text->setPlainText("X");
text->setFont(QFont("Tahoma",24));
text->setPos((160+160+120)/2,140);
scenc->addItem(text);
}
}
in game.h :
class Game : public QObject , public QGraphicsRectItem
{
Q_OBJECT
public:
Game();
QGraphicsScene *scenc;
QGraphicsView *view;
QGraphicsTextItem *text;
void mousePressEvent(QGraphicsSceneMouseEvent *event);
};
The following example illustrates how to do it the right way. Firstly, you have to notice, that Game::mousePressEvent doesn't override any virtual function. It's a good habit to use the override keyword and to drop the virtual keyword in order to be sure, that a virtual function is overwritten.
Game is not derived from QGraphicsScene and has therefore no mousePressEvent member.
Try the following example app.
MyScene.h
#pragma once
#include <QWidget>
#include <QDebug>
#include <QHBoxLayout>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include <QGraphicsSceneMouseEvent>
class MyScene : public QGraphicsScene {
Q_OBJECT
public:
MyScene(QWidget* parent = nullptr) : QGraphicsScene(parent) {
setSceneRect(0, 0, 800, 600);
}
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent) override {
if (mouseEvent->buttons() == Qt::LeftButton)
{
auto text = new QGraphicsTextItem;
addItem(text);
text->setPlainText("X");
text->setPos(mouseEvent->scenePos());
}
}
private:
QGraphicsView* mView;
QGraphicsTextItem* mText;
};
main.cpp
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsTextItem>
#include "MyScene.h"
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto scene = new MyScene;
auto view = new QGraphicsView;
view->setScene(scene);
view->show();
return a.exec();
}

user interface inside QSystemTrayIcon context menu

I'm creatig tray icon application and i want create advanced context menu, like on pictures below, but i only know, how to create simple menues with
QMenu* menu = new QMenu()
menu->addAction(QIcon(), "item", item1Click);
trayIcon->setContextMenu(menu);
How can i do this?
Well, is supose, it's better to show you code:
main.h
#ifndef MAIN_H
#define MAIN_H
#include <QtWidgets/QApplication>
#include <QtCore/QDebug>
#include <QtGui/QIcon>
#include <QtWidgets/QSystemTrayIcon>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QWidgetAction>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QLabel>
class SpinBoxAction : public QWidgetAction
{
public:
SpinBoxAction (const QString& title) : QWidgetAction (NULL)
{
QWidget* Widget = new QWidget (NULL);
QHBoxLayout* Layout = new QHBoxLayout();
QLabel* Label = new QLabel (title);
Layout->addWidget (Label);
SpinBox = new QSpinBox(NULL);
Layout->addWidget (SpinBox);
Widget->setLayout (Layout);
setDefaultWidget(Widget);
}
QSpinBox* spinBox()
{
return SpinBox;
}
private:
QSpinBox* SpinBox;
};
class Reciever : public QObject
{
private:
QSystemTrayIcon* trayIcon;
public:
Reciever()
{
}
void setup(QSystemTrayIcon* trayIcon)
{
this->trayIcon = trayIcon;
}
Q_OBJECT
public slots:
void action(int i)
{
trayIcon->showMessage("changed", "spin box value has been changed", QSystemTrayIcon::NoIcon, 1000);
}
void onActivated(QSystemTrayIcon::ActivationReason reason)
{
trayIcon->showMessage("activated", "tray icon has been activated", QSystemTrayIcon::NoIcon, 1000);
}
};
#endif // MAIN_H
main.cpp
#include <main.h>
#include <QtWidgets/QApplication>
#include <QtCore/QDebug>
#include <QtGui/QIcon>
#include <QtWidgets/QSystemTrayIcon>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QWidgetAction>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QHBoxLayout>
int main(int argc, char** argv)
{
Reciever* reciever = new Reciever();
QApplication app(argc, argv);
QSystemTrayIcon* trayIcon = new QSystemTrayIcon(QIcon(":/images/abc.png"));
if (!trayIcon->isSystemTrayAvailable()) exit(1);
QMenu* menu = new QMenu();
SpinBoxAction* spinBoxAction = new SpinBoxAction("Action Title");
menu->addAction(spinBoxAction);
QObject::connect(spinBoxAction->spinBox(), SIGNAL(valueChanged(int)), reciever, SLOT(action(int)));
trayIcon->setContextMenu(menu);
trayIcon->setVisible(true);
QObject::connect(trayIcon, &QSystemTrayIcon::activated, reciever, &Reciever::onActivated);
reciever->setup(trayIcon);
return app.exec();
}
And it leads to simple list menu with one empty element:

changing number of QPushButton

I'm new in Qt. I have got Class TicTacToeWidget which stores QList with QPushButton.
int m_size is initialized with 3 and works fine and i see 3x3 board, but when i try to change m_size in main.cpp to other value nothing happends. I can't find out why it doesn't work.
#ifndef TICTACTOEWIDGET_H
#define TICTACTOEWIDGET_H
#include <QWidget>
class QPushButton;
class TicTacToeWidget : public QWidget
{
Q_OBJECT
public:
TicTacToeWidget(QWidget *parent = 0);
~TicTacToeWidget();
int size()const;
void resizeBoard(int m);
private:
QList<QPushButton *> m_board;
int m_size;
void setupBoard(int m);
void clearBoard();
};
#endif // TICTACTOEWIDGET_H
And implementation
#include "tictactoewidget.h"
#include <QMessageBox>
#include <QGridLayout>
#include <QPushButton>
#include <QDebug>
TicTacToeWidget::TicTacToeWidget(QWidget *parent)
: QWidget(parent),m_size(3)
{
setupBoard(3);
}
TicTacToeWidget::~TicTacToeWidget()
{
}
int TicTacToeWidget::size() const
{
return m_size;
}
void TicTacToeWidget::resizeBoard(int m)
{
setupBoard(m);
}
void TicTacToeWidget::setupBoard(int m)
{
QGridLayout *gridLayout= new QGridLayout;
m_size=m;
m_board.clear();
for(int i=0;i<m_size;i++)
{
for(int j=0;j<m_size;j++)
{
QPushButton *button= new QPushButton;
button->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
button->setText(" ");
gridLayout->addWidget(button,i,j);
}
}
setLayout(gridLayout);
}
void TicTacToeWidget::clearBoard()
{
for(auto &it:m_board)
{
this->layout()->removeWidget(it);
}
m_board.clear();
}
And main
#include "tictactoewidget.h"
#include <QApplication>
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TicTacToeWidget w;
w.resizeBoard(5);
w.show();
return a.exec();
}
http://doc.qt.io/qt-4.8/qwidget.html#setLayout
If there already is a layout manager installed on this widget, QWidget won't let you install another. You must first delete the existing layout manager

Qt (C++) Pass Variable from Dialog to main.cpp

When i start my Program a Dialog-Window pops up and asks me to enter a name. Once i've entered my Name and press the Button it closes the Dialog and opens the main window.
My question is how i get the variable/ Name i just set in the Dialog into another class / my main.cpp
Main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QtDebug>
#include <QtNetwork>
#include <sstream>
#include "mydialog.h"
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Open Dialog
MyDialog mDialog;
mDialog.setModal(true);
mDialog.exec();
//Open Main Window
GW2::MainWindow w;
w.show();
return a.exec();
}
mydialog.cpp
#include "mydialog.h"
#include "ui_mydialog.h"
#include <QDebug>
using namespace std;
MyDialog::MyDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::MyDialog)
{
ui->setupUi(this);
}
MyDialog::~MyDialog()
{
delete ui;
}
void MyDialog::on_pushButton_clicked()
{
QString MYNAME = ui->lineEdit->text();
close();
}
I can get MYNAME here that works after i press the Button but i need to pass the Variable...
mydialog.h
#ifndef MYDIALOG_H
#define MYDIALOG_H
#include <QDialog>
#include <QString>
namespace Ui {
class MyDialog;
}
class MyDialog : public QDialog
{
Q_OBJECT
public:
explicit MyDialog(QWidget *parent = 0);
~MyDialog();
private slots:
void on_pushButton_clicked();
private:
Ui::MyDialog *ui;
};
#endif // MYDIALOG_Hs
I tried using google and search function but didn'T find anything that worked on my project. Hope you can help me. Cheers
Add this in MyDialog:
QString MyDialog::getName()
{
return ui->lineEdit->text();
}
Then do:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Open Dialog
MyDialog mDialog;
mDialog.setModal(true);
mDialog.exec();
// retrieve the name
QString name = mDialog.getName();
//Open Main Window
GW2::MainWindow w;
w.show();
return a.exec();
}
Note that the dialog could be canceled. You should call accept() rather than close() from on_pushButton_clicked() and later test if the dialog was accepted or not:
if ( mDialog.exec() == QDialog::Accepted )
{
QString name = mDialog.getName();
...

creating QApplication in a different thread

I'm trying to create QApplication in a different thread, but found 2 main problems:
1- I can't interact with GUI
2- some warnings:
WARNING: QApplication was not created in the main() thread.
QObject::startTimer: timers cannot be started from another thread //happens when resizing widget
QObject::killTimer: timers cannot be stopped from another thread
here is the full code: (it may has some memory leaks but for testing purposes it fails)
//main.cpp
#include <QCoreApplication>
#include "cthread.h"
int main(int argc, char *argv[])
{
CThread *MyThread = new CThread;
MyThread->start();
QCoreApplication a(argc, argv);
return a.exec();
}
//CThread.h
#ifndef CTHREAD_H
#define CTHREAD_H
#include <QThread>
#include "theqtworld.h"
class CThread : public QThread
{
Q_OBJECT
public:
CThread();
void run( void );
private:
TheQtWorld *mWorld;
};
#endif // CTHREAD_H
//CThread.cpp
#include "cthread.h"
#include <iostream>
CThread::CThread():mWorld(NULL)
{
}
void CThread::run()
{
std::cout << "thread started" << std::endl;
if(!mWorld)
mWorld = new TheQtWorld();
mWorld->OpenWorld();//now it will init all Qt Stuff inside
// if(mWorld) delete mWorld;
// emit this->exit();
}
//theqtworld.h
#ifndef THEQTWORLD_H
#define THEQTWORLD_H
#include <QObject>
#include "mainwindow.h"
#include <QApplication>
class TheQtWorld : public QObject
{
Q_OBJECT
public:
explicit TheQtWorld(QObject *parent = 0);
int OpenWorld(void);
signals:
public slots:
};
#endif // THEQTWORLD_H
//theqtworld.cpp
#include "theqtworld.h"
TheQtWorld::TheQtWorld(QObject *parent) :
QObject(parent)
{
}
int TheQtWorld::OpenWorld()
{
static int arg = 0;
static char *b[2];
b[0] = "a";
QApplication *a = new QApplication(arg, b);
a->setParent(this);
MainWindow w;
w.show();
return a->exec();
}
I would answer my own question after understanding how to overcome this problem
first the problem was to integrate Qt GUI as a plugin into another Application, so the main issue was the Event loop collision between Qt Events and any other Application Events
my first thoughts was to separate both, so QApplication will stay at a different thread, but this was a totally wrong approach and here is what I have noticed:
1- Qt GUI Must stay in the main() thread so there is no other place for QApplication
2- to avoid the blocking QApplication::exec() , embed QApplication::processEvents() into the other Application Event loop
here is a working code:
//main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication mApp(argc, argv);
MainWindow w;
w.show();
//just for testing and holding the program so it doesn't end
for(int i = 0; i < 100000000; ++i)
{
mApp.processEvents();
}
return 0;
}
edit:thanks to pavel-strakhov for his great suggestion.