I need some help with connection of signal and slot. this is what i have.
In .h file area is the examplar of the class which inherited from QMdiArea. AddSubWindow is slot of this class, and it works correct with other signal. compiler said
"QObject::connect: No such slot MyMdiArea::AddSubWindow(true) in workspace.cpp:37"
#include "workspace.h"
WorkSpace::WorkSpace(QWidget *parent)
: QWidget(parent)
{
HLayout=new QHBoxLayout;
VLayout=new QVBoxLayout;
TabButton = new QPushButton("Tabbed View");
SimpleButton = new QPushButton("Simple View");
AddButton = new QPushButton("Add Window");
HLayout->addWidget(AddButton);
HLayout->addWidget(TabButton);
HLayout->addWidget(SimpleButton);
str="Title";
area = new MyMdiArea(0,str);
area->setViewMode(QMdiArea::TabbedView);
area->setTabsClosable(true);
area->setTabsMovable(true);
VLayout->addLayout(HLayout);
VLayout->addWidget(area);
connect(AddButton,SIGNAL(clicked()),area,SLOT(AddSubWindow(true)));
this->setLayout(VLayout);
//this->show();
}
WorkSpace::~WorkSpace()
{
}
slot
void MyMdiArea::AddSubWindow(bool i)
{
//QString str="заголовок";
MyWindow *widget = new MyWindow(0,str1);
addSubWindow(widget);
widget->setWindowTitle(str1);
widget->show();
}
h. file
#include <QtWidgets/QMainWindow>
#include "ui_workspace.h"
#include "MyMdiArea.h"
#include "mywindow.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTextBlock>
#include <qstring.h>
class WorkSpace : public QWidget
{
Q_OBJECT
public:
WorkSpace(QWidget *parent = 0);
~WorkSpace();
QHBoxLayout *HLayout;
QVBoxLayout *VLayout;
QPushButton *TabButton;
QPushButton *SimpleButton;
QPushButton *AddButton;
MyMdiArea *area;
QString str;
private:
Ui::WorkSpaceClass ui;
};
MyMdiArea.h
#ifndef MYMDIAREA_H
#define MYMDIAREA_H
#include <QWidget>
#include <QMdiArea>
#include <qmessagebox.h>
#include <qpixmap.h>
#include <qpainter.h>
#include "ui_mymdiarea.h"
class MyMdiArea : public QMdiArea
{
Q_OBJECT
public:
QString str1;
void SendSignal();
MyMdiArea(QWidget *parent,QString str);
~MyMdiArea();
void mouseDoubleClickEvent(QMouseEvent *event);
public slots:
void AddSubWindow(bool t);
signals:
void doubleClicked(bool t);
private:
Ui::MyMdiArea ui;
QPixmap logo;
protected:
void paintEvent(QPaintEvent *event);
};
#endif // MYMDIAREA_H
The problem is:
Signal clicked() has no parameter, but slot AddSubWindow() has a parameter of bool type. That's not allowed in Qt.
try change your code like this
.h
public slots:
void AddSubWindow();
.cpp
void MyMdiArea::AddSubWindow()
{
QString str="заголовок";
MyWindow *widget = new MyWindow(0,str1);
addSubWindow(widget);
widget->setWindowTitle(str1);
widget->show();
}
Related
I have my MainWindow with a GraphicsView on which I want to draw a QRubberBand using MouseEvents. Therefore I created a custom GraphicsView class where I have the MouseEvents, however since I am a beginner, I don't know how to connect everything to the MainWindow.
Here's what I got so far:
mousegraphics.h (custom)
#ifndef MOUSEGRAPHICS_H
#define MOUSEGRAPHICS_H
#include <QGraphicsView>
#include <QWidget>
#include <QMainWindow>
#include <QRubberBand>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QEvent>
class MouseGraphics : public QGraphicsView
{
public:
MouseGraphics(QWidget* parent = nullptr);
public slots:
void mousePressEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* e);
void mouseReleaseEvent(QMouseEvent* e);
private:
QRubberBand* rb = nullptr;
// Coordinates
QPoint origin, dest;
};
#endif // MOUSEGRAPHICS_H
mousegraphics.cpp
#include "mousegraphics.h"
MouseGraphics::MouseGraphics(QWidget* parent) : QGraphicsView(parent)
{
}
void MouseGraphics::mousePressEvent(QMouseEvent *e)
{
origin = e->pos();
if(!rb)
{
rb = new QRubberBand(QRubberBand::Line, this);
}
rb->setGeometry(QRect(origin, QSize()));
rb->show();
}
void MouseGraphics::mouseMoveEvent(QMouseEvent *e)
{
rb->setGeometry(QRect(origin, e->pos()).normalized());
}
void MouseGraphics::mouseReleaseEvent(QMouseEvent *e)
{
rb->hide();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QRubberBand>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QEvent>
#include "mousegraphics.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
you should create one class that inherits from QGraphicsView.
because you need mousePressEvent ,mouseReleaseEvent , mouseMoveEvent of QGraphicsView.
Then in MainWindow, you need one QGraphicsScene object and I create one QGridLayout and with the addWidget function add my QGraphicsView object to MainWindow UI.
So I do this :
In graphicsview.h:
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
#include <QObject>
#include <QRubberBand>
class graphicsView: public QGraphicsView
{
public:
graphicsView();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
private:
QRubberBand *rubberBand = nullptr;
QPoint origin;
};
#endif // GRAPHICSVIEW_H
graphicsview.cpp :
#include "graphicsview.h"
#include <QMouseEvent>
#include <QRect>
graphicsView::graphicsView()
{
}
void graphicsView::mousePressEvent(QMouseEvent *event)
{
origin = event->pos();
if (!rubberBand)
{
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
}
rubberBand->setGeometry(QRect(origin, QSize()));
rubberBand->show();
}
void graphicsView::mouseReleaseEvent(QMouseEvent *event)
{
rubberBand->hide();
}
void graphicsView::mouseMoveEvent(QMouseEvent *event)
{
rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}
In mainwindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow: public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
In mainwindow.cpp :
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsScene>
#include <QGridLayout>
#include "graphicsview.h"
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGridLayout *gridLayout;
gridLayout = new QGridLayout(centralWidget());
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
auto scene = new QGraphicsScene(this);
graphicsView *_view = new graphicsView();
_view->setScene(scene);
gridLayout->addWidget(_view);
}
MainWindow::~MainWindow()
{
delete ui;
}
The result is this
:
i am working on QT C++,developing an application that display an image on a label(control) and after click that image the new image will display in other label (control). i create a new project: application->QtWidget Application. then i select class Qdialog. in project file are
- my_qlabel_mouseEvent.pro
and in header folder are
- dialog.h
- my_qlabel.h
and then source folder has files
1: dialog.cpp
2:main.cpp
3: my_qlabel.cpp
and then in form folder has
1: dialog.cpp.
when i add the new class my_qlabel with base class QLabel, type information: QWidget after creating this the setPixmap does not work. its show error the error is that "in constructor 'Dialog::Dialog(QWidget*)' class my_qlabel has no member named setPixmap" please solve this error or reffer me any site or other sources.
**my_qlabel.cpp**
#include "my_qlabel.h"
#include <QPixmap>
my_qlabel::my_qlabel(QWidget *parent) : QWidget(parent)
{
}
void my_qlabel::mouseMoveEvent(QMouseEvent *)
{
emit Mouse_Pos();
}
void my_qlabel::mousePressEvent(QMouseEvent *)
{
emit Mouse_Pressed();
}
void my_qlabel::leaveEvent(QEvent *)
{
emit Mouse_Left();
}
**main.cpp**
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
**dialog.cpp**
#include "dialog.h"
#include "ui_dialog.h"
#include "my_qlabel.h"
#include <QPixmap>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
QPixmap pix("E:/osld/andgate.png");
ui->lblMouse->setPixmap(pix);
connect(ui->lblMouse, SIGNAL(Mouse_Pressed()), this, SLOT(Mouse_Pressed()));
connect(ui->lblMouse, SIGNAL(Mouse_Pos()), this, SLOT(Mouse_current_pos()));
connect(ui->lblMouse, SIGNAL(Mouse_Left()), this, SLOT(Mouse_left()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::Mouse_current_pos()
{
ui->lblMouse_Current_Event->setText("Mouse Moving");
}
void Dialog::Mouse_Pressed()
{
ui->lblMouse_Current_Event->setText("Mouse Pressed");
}
void Dialog::Mouse_left()
{
ui->lblMouse_Current_Event->setText("Mouse Left");
}
**dialog.h**
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private slots:
void Mouse_current_pos();
void Mouse_Pressed();
void Mouse_left();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
**my_qlabel.h**
#ifndef MY_QLABEL_H
#define MY_QLABEL_H
#include <QWidget>
#include <QMouseEvent>
#include <QEvent>
#include <QDebug>
#include <QPixmap>
class my_qlabel : public QWidget
{
Q_OBJECT
public:
explicit my_qlabel(QWidget *parent = 0);
void mouseMoveEvent(QMouseEvent *ev);
void mousePressEvent(QMouseEvent *ev);
void leaveEvent(QEvent *);
signals:
void Mouse_Pressed();
void Mouse_Pos();
void Mouse_Left();
public slots:
};
#endif // MY_QLABEL_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileSystemModel>
#include <QThread>
#include <statusdialog.h>
#include <pbt.h>
#include <stdint.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
//void on_treeView_clicked(const QModelIndex &index);
void onCustomContextMenuTV(const QPoint &point);
void dirSize();
void getSelectedTreeItemSize();
void resultHandle(uint64_t);
signals:
void sizeCalculation(uint64_t);
private:
Ui::MainWindow *ui;
QString sPath;
QFileSystemModel *dirmodel;
QFileSystemModel *filemodel;
QAction *dirSizeAct;
statusDialog statusdialog;
};
#endif // MAINWINDOW_H
pbt.h
#ifndef STATUSDIALOG_H
#define STATUSDIALOG_H
#include <QDialog>
#include <stdint.h>
namespace Ui {
class statusDialog;
}
class statusDialog : public QDialog
{
Q_OBJECT
public:
explicit statusDialog(QWidget *parent = 0);
~statusDialog();
void setProgressbarMax(uint64_t);
private slots:
void on_pushButton_clicked();
private:
Ui::statusDialog *ui;
};
#endif // STATUSDIALOG_H
statusdialog.h
#ifndef STATUSDIALOG_H
#define STATUSDIALOG_H
#include <QDialog>
#include <stdint.h>
namespace Ui {
class statusDialog;
}
class statusDialog : public QDialog
{
Q_OBJECT
public:
explicit statusDialog(QWidget *parent = 0);
~statusDialog();
void setProgressbarMax(uint64_t);
private slots:
void on_pushButton_clicked();
private:
Ui::statusDialog *ui;
};
#endif // STATUSDIALOG_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
sPath = "C:/";
dirmodel = new QFileSystemModel(this);
dirmodel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
dirmodel->setRootPath(sPath);
ui->treeView->setModel(dirmodel);
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->treeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenuTV(const QPoint &)));
connect(this,SIGNAL(sizeCalculation(uint64_t)),this,SLOT(resultHandle(uint64_t)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::resultHandle(uint64_t t_size)
{
statusdialog.setProgressbarMax(t_size);
}
void MainWindow::onCustomContextMenuTV(const QPoint &point)
{
dirSizeAct = new QAction(tr("Size"), this);
connect(dirSizeAct, SIGNAL(triggered()), this, SLOT(dirSize()));
QMenu contextMenu(this);
contextMenu.addAction(dirSizeAct);
QModelIndex index = ui->treeView->indexAt(point);
if (index.isValid()){
contextMenu.exec(ui->treeView->mapToGlobal(point));
}
}
void MainWindow::dirSize()
{
pBT pbt;
pbt.setFP(this->getSelectedTreeItemSize);
QThread thread1;
connect(&thread1,SIGNAL(started()),&pbt,SLOT(startThreadAction()));//Clone the object and it will not work, becouse it is QWidget
pbt.moveToThread(&thread1);
thread1.start();//Starts in the same thread
statusdialog.setModal(true);
statusdialog.exec();
}
void MainWindow::getSelectedTreeItemSize()
{
QModelIndex index = ui->treeView->selectionModel()->selectedIndexes().takeFirst();
QString dirPath = dirmodel->filePath(index);
QDirIterator it(dirPath, QStringList() << "*.*", QDir::Files, QDirIterator::Subdirectories);
uint64_t t_size = 0;
while (it.hasNext()) {
QFile myFile(it.next());
if (myFile.open(QIODevice::ReadOnly)){
t_size += myFile.size();
myFile.close();
}
}
emit sizeCalculation(t_size);
}
pbt.cpp
#include "pbt.h"
pBT::pBT(QObject *parent) : QObject(parent)
{
}
void pBT::startThreadAction()
{
this->fp1();
}
void pBT::setFP(void (*fp1)())
{
this->fp1 = fp1;
}
statusdialog.cpp
#include "statusdialog.h"
#include "ui_statusdialog.h"
statusDialog::statusDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::statusDialog)
{
ui->setupUi(this);
}
statusDialog::~statusDialog()
{
delete ui;
}
void statusDialog::on_pushButton_clicked()
{
this->close();
}
void statusDialog::setProgressbarMax(uint64_t size)
{
ui->progressBar->setMaximum(size);
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
To see more info of what I am doing you can look this topic(It is all about prograssbar and threaded execution of job). Theoretically I whant to run a member function of mainwindow(which use member variables of mainwindow) into new thread(the function is not static) inside slot dirSize()(also member slot of the same class mainwindow), but it seems with QThread it is necessary to create new class(no matter if I will inherit QThread class or use moveToThread function of QObject) and run that class in new thread. If I use C++ thread.h the function I run must be static, nevermind I have tried to create pBT class in which I have function pointer fp1 and public slot startThreadedAction, but when try to buil this error occures:
C:\Users\niki\Documents\EPsimple\mainwindow.cpp:54: error: C3867:
'MainWindow::getSelectedTreeItemSize': function call missing argument
list; use '&MainWindow::getSelectedTreeItemSize' to create a pointer
to member
I don`t want to create function pointer to static function! How can I fix this?
I want to make a program that shows the info of a QGraphicsItem (width and height) by clicking the option "info" inside a context menu I created with the QGraphicsSceneContextMenuEvent. Right now I´m just trying to call a function with a qDebug in it called info.
Here's my code
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "QtCore"
#include "QtGui"
#include "mysquare.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
QGraphicsScene *scene;
MySquare *square;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QWidget>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
square=new MySquare();
scene->addItem(square);
}
Dialog::~Dialog()
{
delete ui;
}
mysquare.h
#ifndef MYSQUARE_H
#define MYSQUARE_H
#include <QPainter>
#include <QGraphicsItem>
#include <QDebug>
#include <QMenu>
class MySquare: public QGraphicsItem
{
public:
MySquare();
QRectF boundingRect() const;
void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QMenu *menu;
QAction *heightAct;
QAction *widthAct;
QAction *color;
private slots:
void info();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
};
#endif // MYSQUARE_H
mysquare.cpp
#include "mysquare.h"
#include<QMenu>
#include <string>
using namespace std;
MySquare::MySquare()
{
}
QRectF MySquare::boundingRect() const
{
return QRectF(100,100,50,50);
}
void MySquare::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QRectF rec = boundingRect();
QBrush brushy(Qt::green);
painter->fillRect(rec,brushy);
painter->drawRect(rec);
}
void MySquare::info()
{
qDebug()<<"HERE'S MY INFO!!!";
}
void MySquare::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
QString height = "Height: "+QString::number(boundingRect().height());
QString width = "Width: "+QString::number(boundingRect().width());
menu = new QMenu();
heightAct = menu->addAction(height);
widthAct = menu->addAction(width);
color = menu->addAction("Change color");
menu->exec(QCursor::pos());
}
To make a "link" between a click on an action in your menu and your slot info(), you need to use the signal/slot mechanism.
You only have to add a QObject::connect(...) in your QMenu initialization.
void MySquare::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
QString height = "Height: "+QString::number(boundingRect().height());
QString width = "Width: "+QString::number(boundingRect().width());
menu = new QMenu();
heightAct = menu->addAction(height);
widthAct = menu->addAction(width);
color = menu->addAction("Change color");
QObject::connect(heightAct, SIGNAL(triggered()), this, SLOT(info()));
menu->exec(QCursor::pos());
}
However, the above code will not compile because signal/slot mechanism work only with subclasses of QObject and QGraphicsItem isn't. So you have to change it to a QGraphicsObject. (Don't forget the Q_OBJECT macro though)
Also, a little out of subject:
Use
#include <QtCore>
instead of
#include "QtCore"
but I really advise you to just include what you need, not the whole QtCore library.
Also, put your includes in your source files instead of your header files except when it's impossible.
Don't mix standard C++ library such as
#include <string>
except when it's absolutely needed. In this case you have to include
#include <QString>
And just simply remove
using namespace std;
hi how to add widget inside widget
i created main widget, and for the main widget headerbar come from another widget.
here the code below
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argl,char *argv[])
{
QApplication test(argl,argv);
mainWindow *window=new mainWindow();
window->setWindowState(Qt::WindowFullScreen);
window->show();
return test.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include <QtGui>
#include "headerbar.h"
#include <QGridLayout>
mainWindow::mainWindow(QWidget *parent) : QWidget(parent)
{
QGridLayout *layout;
headerBar *Header=new headerBar(this);
layout->addWidget(Header,0,0);
this->setLayout(layout);
}
mainWindow::~mainWindow()
{
}
headerbar.cpp
#include "headerbar.h"
headerBar::headerBar(QWidget *parent) : QWidget(parent)
{
this->setMaximumHeight(24);
}
headerBar::~headerBar()
{
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
class mainWindow : public QWidget
{
Q_OBJECT
public:
mainWindow(QWidget *parent = 0);
~mainWindow();
signals:
public slots:
};
#endif // MAINWINDOW_H
headerbar.h
#ifndef HEADERBAR_H
#define HEADERBAR_H
#include <QWidget>
class headerBar : public QWidget
{
Q_OBJECT
public:
headerBar(QWidget *parent = 0);
~headerBar();
signals:
public slots:
};
#endif // HEADERBAR_H
while compile this code no errors. but when i am trying to run it's through error "exited with code -1073741819"
please help me to fix this issue
While you use layout, you have never created and assigned an instance to it:
QGridLayout *layout; // no initialization here
headerBar *Header = new headerBar(this);
layout->addWidget(Header,0,0); // layout is uninitialized and probably garbage
You should create it first before using it:
QGridLayout *layout = new QGridLayout(this);