I have created a simple calculator in Qt , however I am trying to add a button to do me a factorial but its not working
can someone help me with it ?
I already have a method factorial implemented
#include "mainwindow.h"
#include <QtCore/QCoreApplication>
QString value="",total="";
double fNum,sNum;
bool addBool=false, substractBool=false, multiplyBool=false, divideBool=false,Factorbool=false;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
label=new QLabel("0",this);
label->setGeometry(QRect(QPoint(75,25),QSize(50,200)));
clear_button=new QPushButton("C",this);
clear_button->setGeometry(QRect(QPoint(50,300),QSize(50,50)));
connect(clear_button,SIGNAL(released()),this,SLOT(clear()));
equals_button=new QPushButton("=",this);
equals_button->setGeometry(QRect(QPoint(100,300),QSize(50,50)));
connect(equals_button,SIGNAL(released()),this,SLOT(equals()));
add_button=new QPushButton("+",this);
add_button->setGeometry(QRect(QPoint(200,150),QSize(50,50)));
connect(add_button,SIGNAL(released()),this,SLOT(add()));
Factor_button =new QPushButton("n!",this);
Factor_button->setGeometry(QRect(QPoint(250,150),QSize(50,50)));
connect(Factor_button ,SIGNAL(released()),this,SLOT(add()));
substract_button=new QPushButton("-",this);
substract_button->setGeometry(QRect(QPoint(200,200),QSize(50,50)));
connect(substract_button,SIGNAL(released()),this,SLOT(substract()));
multiply_button=new QPushButton("X",this);
multiply_button->setGeometry(QRect(QPoint(200,250),QSize(50,50)));
connect(multiply_button,SIGNAL(released()),this,SLOT(multiply()));
divide_button=new QPushButton("/",this);
divide_button->setGeometry(QRect(QPoint(200,300),QSize(50,50)));
connect(divide_button,SIGNAL(released()),this,SLOT(divide()));
for(int i=0;i<10;i++){
QString digit=QString::number(i);
buttons[i]=new QPushButton(digit,this);
connect(buttons[i],SIGNAL(released()),this,SLOT(buttonPushed()));
}
setGeo();
}
void MainWindow::setGeo()
{
for(int i=0;i<1;i++)
{
buttons[i]->setGeometry(QRect(QPoint(50,300),QSize(50,50)));
}
for(int i=0;i<4;i++)
{
buttons[i]->setGeometry(QRect(QPoint(50*i,250),QSize(50,50)));
}
for(int i=4;i<7;i++)
{
buttons[i]->setGeometry(QRect(QPoint(50*(i-3),200),QSize(50,50)));
}
for(int i=7;i<10;i++)
{
buttons[i]->setGeometry(QRect(QPoint(50*(i-6),150),QSize(50,50)));
}
}
void MainWindow::buttonPushed()
{
QPushButton *button=(QPushButton *)sender();
emit numberEnitted(button->text()[0].digitValue());
value+=QString::number(button->text()[0].digitValue());
label->setText(value);
}
void MainWindow::clear(){
value="";
label->setText(value);
}
void MainWindow::add(){
fNum=value.toDouble();
value="";
label->setText(value);
addBool=true;
}
int factorial( int n)
{
if (n == 0)
return 1;
return n * factorial(n - 1);
}
void MainWindow::equals(){
sNum=value.toDouble();
if(addBool){
total=QString::number(fNum+sNum);
label->setText(total);
}
if(substractBool){
total=QString::number(fNum-sNum);
label->setText(total);
}
if(multiplyBool){
total=QString::number(fNum*sNum);
label->setText(total);
}
if(divideBool){
total=QString::number(fNum/sNum);
label->setText(total);
}
if(Factorbool)
{
total=QString::number(factorial(fNum));
label->setText(total);
}
}
void MainWindow::substract(){
fNum=value.toDouble();
value="";
label->setText(value);
substractBool=true;
}
void MainWindow::multiply(){
fNum=value.toDouble();
value="";
label->setText(value);
multiplyBool=true;
}
void MainWindow::divide(){
fNum=value.toDouble();
value="";
label->setText(value);
divideBool=true;
}
void MainWindow::Factor(){
fNum=value.toDouble();
value="";
label->setText(value);
Factorbool=true;
}
MainWindow::~MainWindow()
{
}
The Main
#include "mainwindow.h"
#include <QApplication>
#include <QDesktopWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.showMaximized();
w.setFixedSize(300,400);
w.move(QApplication::desktop()->screen()->rect().center()-w.rect().center());
w.show();
return a.exec();
}
The .h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QLabel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void numberEnitted(int number);
private slots:
void clear();
void add();
void equals();
void substract();
void multiply();
void divide();
void Factor();
void buttonPushed();
void setGeo();
private:
QLabel *label;
QPushButton *clear_button;
QPushButton *add_button;
QPushButton *equals_button;
QPushButton *substract_button;
QPushButton *multiply_button;
QPushButton *Factor_button;
QPushButton *divide_button;
QPushButton *zero_button;
QPushButton *buttons[10];
};
#endif
I am awaiting your help :)
The signal that is fired when you press the Factor_button is not connected to the correct slot.
This line
connect(Factor_button, SIGNAL(released()), this, SLOT(add()));
should be
connect(Factor_button, SIGNAL(released()), this, SLOT(Factor()));
Related
Using QTCreator, I created the design of a GUI Application. I want to read the input entered by the user from lineEdit and when pushButton is clicked, it should print the factorial of that entered number on the same page. I've read some tutorials but don't understand how to code this using qtc++.
A minimal example is like that:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void hClicked();
void hTextEdit(const QString& data);
private:
QString m_linedata;
QPushButton button;
QLineEdit lineEdit;
QHBoxLayout layout;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <iostream>
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
{
layout.addWidget(&lineEdit);
layout.addWidget(&button);
this->setLayout(&layout);
connect(&lineEdit, &QLineEdit::textChanged, this, &MainWindow::hTextEdit);
connect(&button, &QPushButton::clicked, this , &MainWindow::hClicked);
}
MainWindow::~MainWindow()
{
}
static unsigned factorial(unsigned n)
{
unsigned result = 1;
for (unsigned i=1; i <= n; i++) {
result *= i;
}
return result;
}
void MainWindow::hClicked()
{
if (m_linedata.size() > 0) {
bool res ;
int toint = m_linedata.toInt(&res);
if (res) {
unsigned fact_result = factorial(toint);
lineEdit.clear();
lineEdit.setText(QString::number(fact_result)); }
}
}
void MainWindow::hTextEdit(const QString &data)
{
m_linedata = data;
}
and main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Just do anything you like with the data passed to the auxillary buffer.
This topic might be little lengthy since I have to explain the premise before procceding with the probleme at hand.Firstly my main goal is to have this application in which the user is capable of drag-n-dropping commands from a toolbar in order to form workflows which are send and executed on a remote server.Currently i am working on the client part in qt and it is driving me nuts.
This is my code:
draglabel.h
#ifndef DRAGLABEL_H
#define DRAGLABEL_H
#include <QLabel>
class QDragEnterEvent;
class QDragMoveEvent;
class QFrame;
class DragLabel : public QLabel
{
public:
DragLabel(const QString &text, QWidget *parent);
QString labelText() const;
private:
QString m_labelText;
};
#endif // DRAGLABEL_H
draglabel.c
#include "draglabel.h"
#include <QtWidgets>
DragLabel::DragLabel(const QString &text, QWidget *parent)
: QLabel(parent)
{
QFontMetrics metric(font());
QSize size = metric.size(Qt::TextSingleLine, text);
QImage image(size.width() + 12, size.height() + 12, QImage::Format_ARGB32_Premultiplied);
image.fill(qRgba(0, 0, 0, 0));
QFont font;
font.setStyleStrategy(QFont::ForceOutline);
QLinearGradient gradient(0, 0, 0, image.height()-1);
gradient.setColorAt(0.0, Qt::white);
gradient.setColorAt(0.2, QColor(200, 200, 255));
gradient.setColorAt(0.8, QColor(200, 200, 255));
gradient.setColorAt(1.0, QColor(127, 127, 200));
QPainter painter;
painter.begin(&image);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(gradient);
painter.drawRoundedRect(QRectF(0.5, 0.5, image.width()-1, image.height()-1),
25, 25, Qt::RelativeSize);
painter.setFont(font);
painter.setBrush(Qt::black);
painter.drawText(QRect(QPoint(6, 6), size), Qt::AlignCenter, text);
painter.end();
setPixmap(QPixmap::fromImage(image));
m_labelText = text;
}
QString DragLabel::labelText() const
{
return m_labelText;
}
dragwidget.h
#ifndef DRAGWIDGET_H
#define DRAGWIDGET_H
#include <QWidget>
#include <QFrame>
#include <vector>
#include <set>
#include "draglabel.h"
using namespace std;
class QDragEnterEvent;
class QDropEvent;
class DragWidget : public QFrame
{
public:
DragWidget(QWidget *parent = nullptr);
void setMode(int desiredMode);
void changePairingMode();
void showAvailableCommands();
void initDrawingLayout();
vector<tuple<QString,QString>> actCommands;
vector<tuple<QString,QString>> execCommands;
vector<pair<int,int>>waitingForPair;
int pairingMode=0;
QFrame*drawingCon;
private:
int widgetMode=1;
protected:
void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
void dragMoveEvent(QDragMoveEvent *event) Q_DECL_OVERRIDE;
void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
};
#endif // DRAGWIDGET_H
dragwidget.cpp
#include "draglabel.h"
#include "dragwidget.h"
#include "arrowhead.h"
#include <QtWidgets>
#include <QWidget>
#include <QFrame>
#include <QColor>
#include <tuple>
using namespace std;
static inline QString dndProcMimeType() { return QStringLiteral("application/x-fridgemagnet"); }
DragWidget::DragWidget(QWidget *parent)
: QFrame(parent)
{
drawingCon=new QFrame(this);
QPalette newPalette = palette();
newPalette.setColor(QPalette::Window, Qt::white);
setPalette(newPalette);
setWindowTitle(tr("Drag-and-Drop"));
setMinimumSize(300,300);
setAcceptDrops(true);
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
drawingCon->setPalette(newPalette);
drawingCon->setWindowTitle(tr("Drag-and-Drop"));
drawingCon->setMinimumSize(350,350);
drawingCon->setAcceptDrops(false);
drawingCon->show();
}
void DragWidget::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat(dndProcMimeType())) {
if (children().contains(event->source())) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->acceptProposedAction();
}
} else if (event->mimeData()->hasText()) {
event->acceptProposedAction();
} else {
event->ignore();
}
}
void DragWidget::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat(dndProcMimeType())) {
if (children().contains(event->source())) {
if(widgetMode==1)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
else {
event->ignore();
}
} else {
if(widgetMode==1)
{
event->acceptProposedAction();
}
else
{
if(widgetMode==1)
{
event->accept();
}
else {
event->ignore();
}
}
}
} else if (event->mimeData()->hasText()) {
event->acceptProposedAction();
} else {
event->ignore();
}
}
void DragWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(dndProcMimeType())) {
const QMimeData *mime = event->mimeData();
QByteArray itemData = mime->data(dndProcMimeType());
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QString text;
QPoint offset;
dataStream >> text >> offset;
DragLabel *newLabel = new DragLabel(text, this);
newLabel->move(event->pos() - offset);
newLabel->show();
newLabel->setAttribute(Qt::WA_DeleteOnClose);
if (event->source() == this) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
tuple<QString,QString> addTest;
addTest=make_tuple(text,"");
actCommands.push_back(make_tuple(text,""));
for(auto it:actCommands)
qDebug()<<get<0>(it)<<" "<<get<1>(it);
event->acceptProposedAction();
}
} else {if (event->mimeData()->hasText()) {
if(widgetMode==1)
{
event->accept();
}
else {
event->ignore();
}
event->acceptProposedAction();
}
}
}
void DragWidget::mousePressEvent(QMouseEvent *event)
{
DragLabel *child = static_cast<DragLabel*>(childAt(event->pos()));
if(!pairingMode){
if (!child)
return;
QPoint hotSpot = event->pos() - child->pos();
if(widgetMode==1)
qDebug()<<child->labelText();
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << child->labelText() << QPoint(hotSpot);
QMimeData *mimeData = new QMimeData;
mimeData->setData(dndProcMimeType(), itemData);
mimeData->setText(child->labelText());
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(*child->pixmap());
drag->setHotSpot(hotSpot);
child->hide();
if (drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::CopyAction) == Qt::MoveAction)
child->close();
else {
child->show();
}
}
else {
if(widgetMode==1)
{
DragLabel *child = static_cast<DragLabel*>(childAt(event->pos()));
if (!child)
return;
qDebug()<<"Facem pair cu:"<<child->labelText();
waitingForPair.push_back(make_pair(child->x(),child->y()));
if(waitingForPair.size()==2) {
ArrowHead *line=new ArrowHead(waitingForPair.at(0).first,waitingForPair.at(0).second,waitingForPair.at(1).first,waitingForPair.at(1).second,drawingCon);
line->show();
waitingForPair.erase(waitingForPair.begin(),waitingForPair.begin()+1);
qDebug()<<"Tragem linie";
}
}
}
}
void DragWidget::setMode(int desiredMode)
{
widgetMode=desiredMode;
}
void DragWidget::showAvailableCommands()
{
DragLabel*grep=new DragLabel("grep",this);
grep->move(this->x(),this->y());
grep->show();
DragLabel*cat=new DragLabel("cat",this);
grep->move(this->x()+40,this->y());
cat->show();
DragLabel*wc=new DragLabel("wc",this);
wc->move(this->x()+90,this->y());
wc->show();
}
void DragWidget::changePairingMode()
{
if(pairingMode==1)
pairingMode=0;
else {
pairingMode=1;
}
}
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QTextEdit>
#include "dragwidget.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
protected:
virtual void closeEvent(QCloseEvent *event) override;
private slots:
void handleButton();
void closeAppButton();
void pairButton();
private:
QPushButton *executeCode;
QPushButton *pairCommands;
QPushButton *closeApp;
QTextEdit *inputUser;
QTextEdit *outputServer;
DragWidget * commandLayout=new DragWidget();
DragWidget * availableLayout=new DragWidget();
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
#include "draglabel.h"
#include "dragwidget.h"
#include <QCoreApplication>
#include <QApplication>
#include <QHBoxLayout>
#include <QPushButton>
#include <QCloseEvent>
#include <QTextEdit>
#include <QFrame>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
executeCode=new QPushButton("Execute");
closeApp=new QPushButton("Close");
pairCommands=new QPushButton("Pair");
connect(closeApp, SIGNAL (released()), this, SLOT (closeAppButton()));
connect(pairCommands, SIGNAL (released()), this, SLOT (pairButton()));
void pairButton();
QHBoxLayout * horizontalLayout=new QHBoxLayout();
commandLayout->setMode(1);
availableLayout->setMode(2);
horizontalLayout->addWidget(commandLayout);
horizontalLayout->addWidget(availableLayout);
availableLayout->showAvailableCommands();
QVBoxLayout*inputBoxes=new QVBoxLayout();
inputUser=new QTextEdit();
outputServer=new QTextEdit();
inputBoxes->addWidget(inputUser);
inputBoxes->addWidget(outputServer);
horizontalLayout->addLayout(inputBoxes);
QVBoxLayout*withButtons=new QVBoxLayout();
withButtons->addLayout(horizontalLayout);
withButtons->addWidget(pairCommands);
withButtons->addWidget(executeCode);
withButtons->addWidget(closeApp);
withButtons->addWidget(new QFrame());
setCentralWidget(new QWidget);
centralWidget()->setLayout(withButtons);
}
void MainWindow::handleButton()
{
}
void MainWindow::closeEvent(QCloseEvent *event)
{
event->accept();
}
void MainWindow::closeAppButton()
{
exit(EXIT_SUCCESS);
}
void MainWindow::pairButton()
{
commandLayout->changePairingMode();
qDebug()<<commandLayout->pairingMode;
}
Note:It might seem idiotic but i have the same class for the "toolbar",from where you're supposed to drag commands and also for part where you are supposed to drag commands and pair them.
This is mostly modified code of the fridge-magnets example on the qt website.
The problem that is giving headaches is drawing lines between dragwidget, I have tried drawing everything in the same QFrame but that proved to be disastrous since the whole pixelMap of the instance dragWidget is overwritten at every draw.The solution with which i came up is to overlay a supplimentary QFrame over my dragWidget in order to draw lines there and everyone to be happy,but as always misfortune strikes at every step.When i am trying to click on the command widget everything's fine but clicking on anything other than a DragLabel results in a segfault due to clicking on the QFrame due to childAt() returning the address of the QFrame overlayed on the first instance of dragWdiget();
My main question is: How can i overcome this obstacle
You should use qobject_cast instead of static_cast.
Add Q_OBJECT macro in each class declaration:
class DragLabel : public QLabel
{
Q_OBJECT
public:
//... class declaration ...
}
class DragWidget : public QFrame
{
Q_OBJECT
public:
//... class declaration ...
}
Then use qobject_cast instead of static_cast for childAt(), for example :
DragLabel *child = qobject_cast<DragLabel*>(childAt(event->pos()));
if(!child){
....
}
there was such problem. I have a main and auxiliary form. With the second form, I take two values: the index and the color. I'm transferring to the main form. I get the values in the "setParametr" method. But I can not get them in the "paintEvent" method. QDebug show that the method "setParametr" got the values. When I check the values in "on_pushButton_clicked()" values is 0. What could be the problem. Just started to study Qt
dialog.h
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
void setcolor(int);
int getcolor();
void setindex(int);
int getindex();
private slots:
void ColorIndex();
void on_pushButton_clicked();
private:
Ui::Dialog *ui;
int squareColor;
int Index;
};
dialog.cpp
#include "ui_dialog.h"
#include "dialog.h"
#include "mainwindow.h"
#include "QDebug"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
//connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(ColorIndex()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::setcolor(int color)
{
squareColor = color;
}
int Dialog::getcolor()
{
return squareColor;
}
void Dialog::setindex(int index)
{
Index = index;
}
int Dialog::getindex()
{
return Index;
}
void Dialog::on_pushButton_clicked()
{
MainWindow *main = new MainWindow();
if(ui->radioButton->isChecked()){
setcolor(1);
}
if(ui->radioButton_2->isChecked()){
setcolor(2);
}
if(ui->radioButton_3->isChecked()){
setcolor(3);
}
if(ui->comboBox->currentIndex()==0)
{
setindex(1);
}
if(ui->comboBox->currentIndex()==1)
{
setindex(2);
}
if(ui->comboBox->currentIndex()==2)
{
setindex(3);
}
if(ui->comboBox->currentIndex()==3)
{
setindex(4);
}
qDebug() << QString::number(getcolor());
qDebug() << QString::number(getindex());
main->SetParametr(getindex(),getcolor());
}
mainwindow.h
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QPainterPath>
#include <QColor>
#include <QColorDialog>
#include <QPushButton>
#include <QMainWindow>
#include "dialog.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void setColor(int);
int getColor();
void setIndex(int);
int getIndex();
private:
Dialog *dial = new Dialog();
int fIndex;
int fColor;
private slots:
void on_actionMy_Dialog_triggered();
void paintEvent(QPaintEvent *event);
void on_pushButton_clicked();
signals:
void SetParametr(int index, int color);
private:
Ui::MainWindow *ui;
void onInit();
};
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDebug"
#include "dialog.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
fColor = 0;
fIndex =0;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::SetParametr(int index, int color)
{
fIndex = index;
fColor = color;
qDebug() << QString::number(fColor) + "s";
qDebug() << QString::number(fIndex);
}
/*void MainWindow::setColor(int _color)
{
fColor = _color;
}
int MainWindow::getColor()
{
return fColor;
}
void MainWindow::setIndex(int _index)
{
fIndex = _index;
}
int MainWindow::getIndex()
{
return fIndex;
}
*/
void MainWindow::paintEvent(QPaintEvent *event)
{
QColor red1;
if(fColor==1){
red1 = Qt::red;
}
if(fColor == 2){
red1 = Qt::blue;
}
if(fColor == 3){
red1 = Qt::green;
}
int index1;
if(fIndex == 0)
{
index1 = 0;
}
if(fIndex == 1)
{
index1 = 1;
}
if(fIndex == 2)
{
index1 = 2;
}
if(fIndex == 3)
{
index1 = 3;
}
Q_UNUSED(event);
QPainter painter(this);
if(index1 == 0)
{
painter.setBrush(QBrush(red1, Qt::SolidPattern));
painter.drawEllipse(100, 50, 150, 150);
}
if(index1 == 1)
{
painter.setBrush(QBrush(red1, Qt::SolidPattern));
painter.drawRect(50, 50, 250, 150);
}
if(index1 == 2)
{
painter.setBrush(QBrush(red1, Qt::SolidPattern));
QPolygon polygon;
polygon<<QPoint(175,50)<<QPoint(50,200)<<QPoint(300,200);
painter.drawPolygon(polygon);
}
if(index1 == 3)
{
painter.setBrush(QBrush(red1, Qt::SolidPattern));
painter.drawRect(100, 50, 150, 150);
}
}
void MainWindow::on_actionMy_Dialog_triggered()
{
dial->show();
}
void MainWindow::on_pushButton_clicked()
{
qDebug() << QString::number(fColor);
qDebug() << QString::number(fIndex);
}
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
I created a small test application with 2 widgets, one inside the other.
I reimplemented the mouse move, press and release events for the inner widget in order to be able to move it inside its bigger parent with drag&drop.
However, when I move it a black trace appears from top and from left. This is how it looks:
Here is my code:
main.cpp:
#include <QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPaintEvent>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
void paintEvent(QPaintEvent *e);
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
#include "innerwidget.h"
#include <QPainter>
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
new InnerWidget(this);
resize(400, 200);
}
Widget::~Widget()
{
}
void Widget::paintEvent(QPaintEvent* e)
{
QPainter p(this);
p.setBrush(Qt::lightGray);
p.drawRect(e->rect());
}
innerwidget.h:
#ifndef INNERWIDGET_H
#define INNERWIDGET_H
#include <QWidget>
#include <QPaintEvent>
class InnerWidget : public QWidget
{
Q_OBJECT
public:
explicit InnerWidget(QWidget *parent = 0);
~InnerWidget();
protected:
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void paintEvent(QPaintEvent *e);
private:
bool m_leftButtonPressed;
QPoint m_mousePosOnBar;
};
#endif // INNERWIDGET_H
innerwidget.cpp:
#include "innerwidget.h"
#include <QPainter>
#include <QPaintEvent>
#include <QStyleOption>
InnerWidget::InnerWidget(QWidget *parent) : QWidget(parent)
{
setGeometry(10, 10, 100, 100);
setStyleSheet("background-color: red");
}
InnerWidget::~InnerWidget()
{
}
void InnerWidget::mousePressEvent(QMouseEvent* e)
{
if(e->button() == Qt::LeftButton)
{
m_mousePosOnBar = e->pos();
m_leftButtonPressed = true;
}
e->accept();
}
void InnerWidget::mouseReleaseEvent(QMouseEvent* e)
{
if(e->button() == Qt::LeftButton)
{
m_leftButtonPressed = false;
}
e->accept();
}
void InnerWidget::mouseMoveEvent(QMouseEvent* e)
{
if(m_leftButtonPressed)
{
move(e->pos().x() - m_mousePosOnBar.x() + geometry().x(),
e->pos().y() - m_mousePosOnBar.y() + geometry().y());
}
e->accept();
}
void InnerWidget::paintEvent(QPaintEvent* e)
{
Q_UNUSED(e)
QPainter p(this);
QStyleOption opt;
opt.init(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
EDIT:
The trace disappears when I call Widget::repaint but then I would have to install an event filter on InnerWidget and repaint everytime it moves. I would want a cleaner solution without having to use event filters...
Can anyone tell me what is really happening?
Calling QWidget::update() in Widget::paintEvent solved the problem:
void Widget::paintEvent(QPaintEvent* e)
{
QPainter p(this);
p.setBrush(Qt::lightGray);
p.drawRect(e->rect());
update();
}