I want my form to have a QStackedWidget with 2 (at least) pages and each of them has a QChartView.
In the form editor, through the 'promote' menu, I made a QChartView from QGraphicView. (screenshoot (so far there is only 1 QChartView on it - so that i can see which page is open)).
From the main window, when one of the buttons is pressed, I want to open the above windows in a loop:
void Widget::ShowStudioCharts() noexcept
{
for(auto & e : this->userInfoVector){
Form *pForm = new Form();
pForm->provideStudioData(&e.studiosStats, e.nickname);
pForm->processStudioStats();
pForm->show();
}
}
I tried to do it like this:
Form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include <QPieSeries>
#include <QChart>
#include <QChartView>
#include <QGridLayout>
#include <vector>
#include <map>
#include <QStackedWidget>
#include <QtGlobal>
#include <QRectF>
#include <QRect>
#include <QPushButton>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
void provideStudioData(std::map<std::string, std::size_t> *studiosStats, const std::string &nickname) noexcept;
void processStudioStats() noexcept;
private slots:
void on_pushButton_2_clicked();
private:
std::vector<std::map<std::string, size_t>*> stats;
std::vector<std::string> nicknames;
Ui::Form *ui;
};
#endif // FORM_H
Form.cpp
#include "form.h"
#include "ui_form.h"
#include <QPieSeries>
#include <QPieSlice>
#include <QChart>
using namespace QtCharts;
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::provideStudioData(std::map<std::string, size_t> *studiosStats, const std::string &nickname) noexcept
{
this->stats.push_back(studiosStats);
this->nicknames.push_back(nickname);
}
void Form::processStudioStats() noexcept
{
srand(time(0));
QPieSeries *series = new QPieSeries();
// for (const auto & e : this->stats ){
// //QBarSet *set0 = new QBarSet("1");
// for ( const auto & a : *e){
// //*set0 << a.second;
// qDebug( (a.first + " " + std::to_string(a.second)).c_str());
// }
// }
for ( const auto & a : *this->stats[0]){
QPieSlice * slice = new QPieSlice();
slice->setColor(QColor(rand()%255, rand()%255, rand()%255));
slice->setValue(a.second);
slice->setLabel(a.first.c_str());
series->append(slice);
}
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::AnimationOption::AllAnimations);
chart->addSeries(series);
//chart->setPlotArea(QRectF(200,0,1400,1100));
//chart->legend()->detachFromChart();
chart->legend()->setBackgroundVisible(true);
chart->legend()->setBrush(QBrush(QColor(128, 128, 128, 128)));
chart->legend()->setPen(QPen(QColor(192, 192, 192, 192)));
//chart->legend()->setGeometry(QRectF(20,20,200,1000));
chart->setTitle(QString::fromStdString(this->nicknames[0]));
this->setWindowTitle(QString::fromStdString(this->nicknames[0]));
chart->legend()->setAlignment(Qt::AlignLeft);
ui->graphicsView = new QChartView(chart);
ui->graphicsView->show();
//ui->stackedWidget->show();
}
void Form::on_pushButton_2_clicked()
{
if(0 == this->ui->stackedWidget->currentIndex())
this->ui->stackedWidget->setCurrentIndex(1);
else if(1 == this->ui->stackedWidget->currentIndex())
this->ui->stackedWidget->setCurrentIndex(0);
}
The code is compiled, windows are opened. But the problem is that my chart is displayed in another window above the opened one.
This is obviously the result of
ui->graphicsView->show();
But if i remove this line, then the graph is not visible at all.
Help please, thanks in advance.
Doing ui->graphicsView = new QChartView(chart); does not replace the QChartView, you are just assigning the pointer. The solution is to reuse the existing QChartView so it changes to: ui->graphicsView->setChart(chart);.
Related
Sorry, I use google translator.
I am exploring how QGraphicsItem works.
But I don’t understand how the data is transmitted through the pointers to the scene.
Here is a code
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qmyscene.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QMyScene(this);
ui->graphicsView->setScene(scene);
scene->setSceneRect(0,0,800,600);
}
MainWindow::~MainWindow()
{
delete ui;
}
qmyscene.cpp
#include "qmyscene.h"
#include "qpixitem.h"
#include <qdebug.h>
QMyScene::QMyScene(QObject *parent) : QGraphicsScene(parent)
{
QPixItem *pix1 = new QPixItem (this,100,100);
QPixItem *pix2 = new QPixItem (this,50,50);
}
QMyScene::~QMyScene()
{
}
qpixitem.cpp
#include "qpixitem.h"
#include <QMessageBox>
QPixItem::QPixItem (QGraphicsScene *MyScene,int x,int y): QGraphicsPixmapItem()
{
QPixmap pic (":/Items/OutLet.png");
this->setPixmap(pic);
this->setPos(x, y);
this->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsGeometryChanges);
qDebug() << "create";
QGraphicsLineItem* line = MyScene->addLine(QLineF(40, 40, 80, 80));
MyScene->addItem(this);
}
QVariant QPixItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange)
{
QPointF newPos = value.toPointF();
int p1 = newPos.x();
int p2 = newPos.y();
MyScene->addLine(QLineF(40,40,p1, p2)); //error
//this->line->setLine(QLineF(40,40,p1, p2)); //error
qDebug() << "Scene::move";
}
return QGraphicsItem::itemChange(change, value);
}
qmyscene.h
#ifndef QMYSCENE_H
#define QMYSCENE_H
#include <QGraphicsScene>
#include <QDebug>
class QMyScene: public QGraphicsScene
{
Q_OBJECT
public:
explicit QMyScene(QObject *parent = 0);
~QMyScene();
private:
};
#endif // QMYSCENE_H
qpixitem.h
#ifndef QPIXITEM_H
#define QPIXITEM_H
#include <QGraphicsItem>
#include "QGraphicsScene"
#include "mainwindow.h"
#include <QGraphicsPixmapItem>
class QPixItem: public QGraphicsPixmapItem
{
public:
QPixItem (QGraphicsScene *MyScene,int x,int y);
QGraphicsScene *MyScene;
int x,y;
private:
QGraphicsLineItem* line;
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
};
#endif // QPIXITEM_H
// error - the lines cause an error (closing the program due to memory access), I am sure that this is due to improperly used pointers. How to use them correctly in such code?
You never seem to allocate this->line.
Did you mean:
this->line = MyScene->addLine(QLineF(40, 40, 80, 80));
Instead of
QGraphicsLineItem* line = MyScene->addLine(QLineF(40, 40, 80, 80));
In my open source project I want to add a sector scanner function. For this I tried to create a Widget similar to the of Defragment software products.
All is working expect the issue that I cannot bring the control scrollable. My code will always generate a forced size so the mdichild (parent) will resize and the scrolling is inside the MdiArea not inside the window. Means it will scroll the mdiHeader out of the view.
I expect that the control itself becomes scrollbars to scroll and the mdichild window will keep it size. My code is:
MDICHild: mdichild_scan.cpp
#include <QtWidgets>
#include "mdichild_scan.h"
#include "FoxSDKBurningLib.h"
#include "mainwindow.h"
#include "settingspages.h"
#include "messanger.h"
MdiChildScan::MdiChildScan(QWidget* parent, const QString &device)
:strBurnDrive(device){
setAttribute(Qt::WA_DeleteOnClose);
mProjectType = RuleManager::TYPE_PROJECT_DEVICEINFO;
thisSuccessfullCreated = true;
QString wTitle = tr("Hex ");
wTitle += " (";
wTitle += strBurnDrive;
wTitle += ")";
setWindowTitle(wTitle);
QVBoxLayout * dlgSplitter = new QVBoxLayout(this);
QHBoxLayout * topNav = new QHBoxLayout(this);
QWidget * wdgSplitter = new QWidget(this);
QLabel *labelTopNav = new QLabel(this);
labelTopNav->setText(tr("This is a header"));
topNav->addWidget(labelTopNav);
topNav->setContentsMargins(1,8,1,0);
dlgSplitter->setContentsMargins(0,0,0,0);
dlgSplitter->setSpacing(0);
dlgSplitter->setMargin(0);
dlgSplitter->addLayout(topNav);
scanBoard = new QScanBoard(45, 65);
dlgSplitter->addWidget(scanBoard);
wdgSplitter->setLayout(dlgSplitter);
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
this->setCentralWidget(wdgSplitter);
}
mdichild_scan.h
#ifndef MDICHILD_SCAN_H
#define MDICHILD_SCAN_H
#include <QMainWindow>
#include <QtWidgets>
#include <QListView>
#include <QSplitter>
#include <QLabel>
#include "mdichild_base.h"
#include "FoxSDKBurningLib.h"
#include "vrulemanager.h"
#include "QScanBoard.h"
class MdiChildScan : public MdiChildBase
{
Q_OBJECT
public:
MdiChildScan(QWidget* parent, const QString &device);
RuleManager::ProjectType GetProjectType() {return mProjectType;}
bool thisSuccessfullCreated;
protected:
RuleManager::ProjectType mProjectType;
QString strBurnDrive;
private:
QScanBoard* scanBoard;
};
#endif
The control itsel: QScanBoard.cpp
#include "QScanBoard.h"
#include <QGridLayout>
#include <QScrollBar>
#include <QSet>
QScanBoard::QScanBoard(unsigned int numRows, unsigned int numCols, QWidget* parent)
: QAbstractScrollArea(parent)
, m_numRows(numRows)
, m_numCols(numCols)
{
setupLayout();
createTiles();
}
void QScanBoard::setupLayout()
{
this->setAttribute(Qt::WA_LayoutUsesWidgetRect);
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
auto layout = new QGridLayout;
layout->setSpacing(0);
layout->setMargin(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSizeConstraint(QLayout::SetFixedSize);
setLayout(layout);
setFocusPolicy(Qt::StrongFocus);
verticalScrollBar()->setValue(0);
}
void QScanBoard::createTiles()
{
for (unsigned int r = 0; r < m_numRows; ++r)
{
m_tiles += QList<QScanTile*>{};
for (unsigned int c = 0; c < m_numCols; ++c)
{
// add a new tile to the row
m_tiles[r] += new QScanTile({ r, c }, this);
static_cast<QGridLayout*>(this->layout())->addWidget(m_tiles[r][c], r, c);
}
}
m_tiles[0][0]->setDown(true);
viewport() -> update();
}
QScanBoard.h
#ifndef QSCANBOARD_H
#define QSCANBOARD_H
#pragma once
#include <QList>
#include <QFrame>
#include <QSet>
#include <QAbstractScrollArea>
#include "QScanTile.h"
class QScanBoard : public QAbstractScrollArea
{
Q_OBJECT
public:
QScanBoard(unsigned int numRows, unsigned int numCols, QWidget* parent = nullptr);
unsigned int numCols() const { return m_numCols; }
unsigned int numRows() const { return m_numRows; }
signals:
void initialized();
private:
void createTiles();
void setupLayout();
private:
unsigned int m_numRows;
unsigned int m_numCols;
QList<QList<QScanTile*>> m_tiles;
QSet<QScanTile*> m_sectors;
};
#endif // QSCANBOARD_H
Progress Item: QScanTile.cpp
#include "QScanTile.h"
#include <thread>
#include <chrono>
#include <QDebug>
#include <QState>
#include <QFinalState>
#include <QMouseEvent>
#include <QSizePolicy>
const QString QScanTile::unrevealedStyleSheet =
"QScanTile"
"{"
" border: 1px solid darkgray;"
" background: qradialgradient(cx : 0.4, cy : -0.1, fx : 0.4, fy : -0.1, radius : 1.35, stop : 0 #fff, stop: 1 #bbb);"
" border - radius: 1px;"
"}";
const QString QScanTile::revealedStyleSheet =
"QScanTile"
"{"
" border: 1px solid lightgray;"
"}";
const QString QScanTile::revealedWithNumberStylesheet =
"QScanTile"
"{"
" color: %1;"
" font-weight: bold;"
" border: 1px solid lightgray;"
"}";
QIcon QScanTile::blankIcon()
{
static QIcon icon = QIcon();
return icon;
}
QScanTile::QScanTile(QScanTileLocation location, QWidget* parent /*= nullptr*/)
: m_adjacentFlaggedCount(0)
, m_location(location)
, QPushButton(parent)
{
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setCheckable(true);
this->setIcon(blankIcon());
this->setStyleSheet(unrevealedStyleSheet);
}
QScanTile::~QScanTile()
{
}
QScanTileLocation QScanTile::location() const
{
return m_location;
}
QSize QScanTile::sizeHint() const
{
return QSize(12, 12);
}
QScanTile.h
#ifndef QSCANTILE_H
#define QSCANTILE_H
#pragma once
#include <QPushButton>
#include <QList>
#include <QStateMachine>
#include <QState>
#include <QFinalState>
#include <QSignalMapper>
struct QScanTileLocation
{
unsigned int row;
unsigned int column;
};
class QScanTile : public QPushButton
{
Q_OBJECT
public:
QScanTile(QScanTileLocation location, QWidget* parent = nullptr);
virtual ~QScanTile() override;
QScanTileLocation location() const;
virtual QSize sizeHint() const override;
static QIcon blankIcon();
private:
QScanTileLocation m_location;
static const QString unrevealedStyleSheet;
static const QString revealedStyleSheet;
static const QString revealedWithNumberStylesheet;
};
#endif // QSCANTILE_H
I hope someone can help me why the control will not get the expected scrollbars. (See in red)
Solved myself. QAbstractArea was the wrong way. Now it works perfect.
Added a ScrollArea to the MDI Child and put the Control inside this
scanBoard = new QScanBoard(200, 83);
scrollArea->setWidget(scanBoard);
Control changed from QAbstractScrollArea to QFrame.
I'm trying to create a program that accepts images through drag and drop and shows those images on my UI, then I want to rename them and save them.
I got the drag and drop to work, but I have some issues with my Image placement and I can't seem to find where I'm making my mistake.
In the image you see my UI during runtime, in the top left you can see a part of the image I dragged into the green zone(this is my drag and drop zone that accepts images). The position I actually want it to be in should be the red square. The green zone is a Dynamic created object called Imagehandler that I created to handle the drag and drop of the images. The Red square is my own class that inherits from QLabel, I called it myiconclass. This class should hold the actual image data.
I think my mistake has to do with the layouts, but I can't see it.
Could I get some help with this please?
Imagehandler.h
#ifndef IMAGEHANDLER_H
#define IMAGEHANDLER_H
#include <QObject>
#include <QWidget>
#include <QLabel>
#include <QDrag>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QList>
#include <QDebug>
//this class is designed to help me take in the images with drag and drop
class ImageHandler : public QWidget
{
Q_OBJECT
public:
explicit ImageHandler(QWidget *parent = nullptr);
QList<QImage> getImageListMemory() const;
void setImageListMemory(const QList<QImage> &value);
QList<QUrl> getUrlsMemory() const;
void setUrlsMemory(const QList<QUrl> &value);
private:
//QWidget Icon;
QLabel Icon;
QList <QImage> imageListMemory;
QList <QUrl> urlsMemory;
protected:
void dragEnterEvent(QDragEnterEvent * event);
void dragLeaveEvent(QDragLeaveEvent * event);
void dragMoveEvent(QDragMoveEvent * event);
void dropEvent(QDropEvent * event);
signals:
void transferImageSignal(QList <QImage>);
public slots:
};
#endif // IMAGEHANDLER_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QImageReader>
#include <QList>
#include <QWidget>
#include <QLabel>
#include <myiconclass.h>
#include <imagehandler.h>
#include <QGridLayout>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QList<QImage> getImageListMemory() const;
void setImageListMemory(const QList<QImage> &value);
private:
Ui::MainWindow *ui;
QLabel Icon;
QList <QImage> imageListMemory;
QList <QUrl> urlsMemory;
QList<QWidget *> labelList;
ImageHandler * ImageHandlerMemory;
QGridLayout * grid2;
QList <MyIconClass *> memory;
signals:
public slots:
void setIconSlot(QList <QImage>);
};
#endif // MAINWINDOW_H
myiconclass.h
#ifndef MYICONCLASS_H
#define MYICONCLASS_H
#include <QWidget>
#include <QLabel>
//this class is based on a Qlabel and is only made so it can help me with the actual images, gives me more members if I need it
class MyIconClass : public QLabel
{
Q_OBJECT
public:
explicit MyIconClass(QWidget *parent = nullptr);
int getMyNumber() const;
void setMyNumber(int value);
private:
int myNumber;
signals:
public slots:
};
#endif // MYICONCLASS_H
imagehandler.cpp
#include "imagehandler.h"
ImageHandler::ImageHandler(QWidget *parent) : QWidget(parent)
{
setAcceptDrops(true);
}
QList<QImage> ImageHandler::getImageListMemory() const
{
return imageListMemory;
}
void ImageHandler::setImageListMemory(const QList<QImage> &value)
{
imageListMemory = value;
}
QList<QUrl> ImageHandler::getUrlsMemory() const
{
return urlsMemory;
}
void ImageHandler::setUrlsMemory(const QList<QUrl> &value)
{
urlsMemory = value;
}
void ImageHandler::dragEnterEvent(QDragEnterEvent * event)
{
event->accept();
}
void ImageHandler::dragLeaveEvent(QDragLeaveEvent * event)
{
event->accept();
}
void ImageHandler::dragMoveEvent(QDragMoveEvent * event)
{
event->accept();
}
void ImageHandler::dropEvent(QDropEvent * event)
{
QList <QImage> imageList2;
QList <QUrl> urls;
QList <QUrl>::iterator i;
urls = event->mimeData()->urls();
//imageList.append(event->mimeData()->imageData());
foreach (const QUrl &url, event->mimeData()->urls())
{
QString fileName = url.toLocalFile();
qDebug() << "Dropped file:" << fileName;
qDebug()<<url.toString();
QImage img;
if(img.load(fileName))
{
imageList2.append(img);
}
}
emit transferImageSignal(imageList2);
this->setUrlsMemory(urls);
this->setImageListMemory(imageList2);
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ImageHandler * handler = new ImageHandler(this);
handler->show();
QGridLayout *grid = new QGridLayout;
grid->addWidget(handler, 0, 0);
ui->groupBoxIcon->setLayout(grid);
ImageHandlerMemory = handler;
//connect(handler,SIGNAL(handler->transferImageSignal(QList <QUrl>)),this,SLOT(setIconSlot(QList <QUrl>)));
connect(handler,SIGNAL(transferImageSignal(QList<QImage>)),this,SLOT(setIconSlot(QList<QImage>)));
}
MainWindow::~MainWindow()
{
delete ui;
}
QList<QImage> MainWindow::getImageListMemory() const
{
return imageListMemory;
}
void MainWindow::setImageListMemory(const QList<QImage> &value)
{
imageListMemory = value;
}
void MainWindow::setIconSlot(QList<QImage> images)
{
printf("succes!");
this->setImageListMemory(images); //save the images to memory
QGridLayout *grid = new QGridLayout; //create the grid layout I want my images to be in
// create counters to remember the row and column in the grid
int counterRow =0;
int counterColumn =0;
int counter3 =0;
int counterImages = 0;
//iterate over each image in the list
QList <QImage>::iterator x;
for(x = imageListMemory.begin(); x != imageListMemory.end(); x++)
{
MyIconClass * myLabel = new MyIconClass(this); //create an object of my own class (which is a Qlabel with an int member)
QPixmap pixmap(QPixmap::fromImage(*x)); //create a pixmap from the image in the iteration
myLabel->setPixmap(pixmap); //set the pixmap on my label object
myLabel->show();
memory.append(myLabel); //add it to the memory so I can recal it
counterImages++;
}
while(counter3 < images.count())
{
grid2->addWidget(memory.value(counter3), counterRow, counterColumn);
counterColumn++;
counter3++;
if(counterColumn >= 5)
{
counterRow++;
counterColumn =0;
}
}
if(ImageHandlerMemory->layout() == 0)
{
ImageHandlerMemory->setLayout(grid2);
}
}
myiconclass.cpp
#include "myiconclass.h"
MyIconClass::MyIconClass(QWidget *parent) : QLabel(parent)
{
}
int MyIconClass::getMyNumber() const
{
return myNumber;
}
void MyIconClass::setMyNumber(int value)
{
myNumber = value;
}
As Benjamin T said I had to change this:
MyIconClass * myLabel = new MyIconClass(this);
into this:
MyIconClass * myLabel = new MyIconClass(ImageHandlerMemory);
Thanks Benjamin!
PS, I also had to add this line in my mainwindow constructor:
grid2 = new QGridLayout;
I'm trying to create a scrollbar for my labels. For the moment, if the users create too many labels, the sizes of the button and of the text zone are reduced, that's why I wanted to create a scrollbar then if there is too many labels, they will not change the aspect of the window.
This is my actual code :
#include <iostream>
#include <QApplication>
#include <QPushButton>
#include <QLineEdit>
#include <QWidget>
#include <QFormLayout>
#include "LibQt.hpp"
LibQt::LibQt() : QWidget()
{
this->size_x = 500;
this->size_y = 500;
QWidget::setWindowTitle("The Plazza");
setFixedSize(this->size_x, this->size_y);
manageOrder();
}
LibQt::~LibQt()
{
}
void LibQt::keyPressEvent(QKeyEvent* event)
{
if (event->key() == Qt::Key_Escape)
QCoreApplication::quit();
else
QWidget::keyPressEvent(event);
}
void LibQt::manageOrder()
{
this->converLayout = new QFormLayout;
this->testline = new QLineEdit;
this->m_button = new QPushButton("Send");
this->m_button->setCursor(Qt::PointingHandCursor);
this->m_button->setFont(QFont("Comic Sans MS", 14));
this->converLayout->addRow("Order : ", this->testline);
this->converLayout->addWidget(this->m_button);
QObject::connect(m_button, SIGNAL(clicked()), this, SLOT(ClearAndGetTxt()));
CreateLabel("test");
CreateLabel("test2");
}
void LibQt::CreateLabel(std::string text)
{
QString qstr = QString::fromStdString(text);
this->label = new QLabel(qstr);
this->converLayout->addWidget(this->label);
this->setLayout(converLayout);
}
std::string LibQt::ClearAndGetTxt()
{
QString txt = this->testline->text();
if (!txt.isEmpty())
{
this->usertxt = txt.toStdString();
std::cout << this->usertxt << std::endl;
this->testline->clear();
CreateLabel(this->usertxt);
return (this->usertxt);
}
return (this->usertxt);
}
std::string LibQt::getUsertxt()
{
return (this->usertxt);
}
And this is the .hpp :
#ifndef _LIBQT_HPP_
#define _LIBQT_HPP_
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QKeyEvent>
class LibQt : public QWidget
{
Q_OBJECT
public:
LibQt();
~LibQt();
void manageOrder();
std::string getUsertxt();
void keyPressEvent(QKeyEvent *event);
void keyPressEventEnter(QKeyEvent *event);
void CreateLabel(std::string text);
public slots:
std::string ClearAndGetTxt();
protected:
int size_x;
int size_y;
QPushButton *m_button;
QLineEdit *testline;
std::string usertxt;
QLabel *label;
QFormLayout *converLayout;
};
#endif /* _LIBQT_HPP_ */
there are different solutions depending on what precisely do you want
QTextEdit is Qt widget class for scrollable text. By turning off text interaction flags, frame style and unsetting background color you will basically get scrollable QLabel
QScrollArea as a more generic solution
I'm having some problems with my script. Everything was fine for a while but now when I #include a file I get errors that occur on any line pointing to another class. Like these (there's actually 12 of them..):
x:\development\inkpuppet\newdialog.h:20: error: C2143: syntax error : missing ';' before '*'
x:\development\inkpuppet\newdialog.h:20: error: C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Occurs when I say InkPuppet *pointerToPuppet;
Edit: the include I can't put in the header is inkspot.h in the inkpuppet.h header.
For each pointer I get the two above errors x3.
Then I get errors because obviously the pointers no longer work.
I'm going to go ahead and post all my code because I do not know which parts will be relevant.
inkpuppet.h
#ifndef INKPUPPET_H
#define INKPUPPET_H
#include "inkspot.h"
//#include "ui_inkpuppet.h"
#include <QMainWindow>
#include <QWidget>
namespace Ui {
class InkPuppet;
}
class InkPuppet : public QMainWindow
{
Q_OBJECT
public:
explicit InkPuppet(QWidget *parent = 0);
~InkPuppet();
Ui::InkPuppet *ui;
private slots:
void setMinimum(int value);
void setMaximum(int value);
void actionNew();
void actionAbout();
void setSpacing(int);
void on_colorAButton_clicked();
};
#endif // INKPUPPET_H
inkpuppet.cpp
#include "inkpuppet.h"
#include "ui_inkpuppet.h"
#include "newdialog.h"
#include "aboutdialog.h"
#include "inkspot.h"
#include <Qt>
#include <QtCore>
#include <QtGui>
#include <QWidget>
#include <QDialog>
#include <QMainWindow>
#include <QDebug>
#include <QColorDialog>
InkPuppet::InkPuppet(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::InkPuppet)
{
ui->setupUi(this);
//connect the frame range boxes to the timeslider
connect(ui->lowerFrameBox, SIGNAL(valueChanged(int)), this, SLOT(setMinimum(int)));
connect(ui->upperFrameBox, SIGNAL(valueChanged(int)), this, SLOT(setMaximum(int)));
//connect tool palette items
connect(ui->spacingBox, SIGNAL(valueChanged(int)), this, SLOT(setSpacing(int)));
connect(ui->colorAButton, SIGNAL(clicked()), this, SLOT(on_colorAButton_clicked()));
//connect the menu items
connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(actionNew()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(actionAbout()));
}
void InkPuppet::setMinimum(int value)
{
ui->timeSlider->setMinimum(value);
ui->frameNumberBox->setMinimum(value);
}
void InkPuppet::setMaximum(int value)
{
ui->timeSlider->setMaximum(value);
ui->frameNumberBox->setMaximum(value);
}
void InkPuppet::setSpacing(int)
{
InkSpot *spot = new InkSpot(this);
//spot->puppet = this;
spot->spacing = ui->spacingBox->value();
}
//menu items
void InkPuppet::actionNew()
{
NewDialog *nDialog = new NewDialog;
//nDialog->createNew(this);
nDialog->pointerToPuppet = this;
nDialog->setModal(true);
nDialog->show();
}
void InkPuppet::actionAbout()
{
AboutDialog *aDialog = new AboutDialog;
aDialog->setModal(true);
aDialog->show();
}
//tool menu
void InkPuppet::on_colorAButton_clicked()
{
// QColor color = QColorDialog(QColor->setRgb(255, 0, 0));
// //color->setRgb(0, 0, 0);
// qDebug() << "done";
// if(color->isValid())
// {
// QString qss = QString("background-color: %1").arg(color->name());
// ui->colorAButton->setStyleSheet(qss);
// }
}
InkPuppet::~InkPuppet()
{
delete ui;
}
inkspot.h
#ifndef INKSPOT_H
#define INKSPOT_H
#include "newdialog.h"
//#include "inkpuppet.h"
#include <QObject>
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QLabel>
#include <QPoint>
#include <QImage>
namespace Ui {
class InkSpot;
}
class InkSpot : public QWidget
{
Q_OBJECT
public:
explicit InkSpot(QWidget *parent = 0);
void draw(QPainter *painter);
QWidget *widget;
int canvasWidth;
int canvasHeight;
float spacing;
NewDialog *newDialog;
QPixmap pixmap;
signals:
//int sendWidthOfCanvas();
//void sendHeightOfCanvas();
public slots:
//void widthOfCanvas();
//void heightOfCanvas();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
private:
void drawLineTo(const QPoint &endPoint);
bool drawing;
QPoint lastPoint;
QImage image;
QImage test2;
Ui::InkSpot *ui;
};
#endif // INKSPOT_H
inkspot.cpp
#include "inkspot.h"
#include "inkpuppet.h"
#include "ui_inkpuppet.h"
#include "newdialog.h"
#include "ui_newdialog.h"
#include <QtCore>
#include <QtGui>
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
InkSpot::InkSpot(QWidget *parent) :
QWidget(parent)
{
widget = this;
drawing = false;
//spacing = puppet->ui->spacingBox->value();
spacing = 1;//puppet->ui->spacingBox->value();
}
void InkSpot::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
lastPoint = event->pos();
drawing = true;
}
}
void InkSpot::mouseMoveEvent(QMouseEvent *event)
{
if((event->buttons() & Qt::LeftButton) && drawing)
{
drawLineTo(event->pos());
}
}
void InkSpot::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton && drawing)
{
drawLineTo(event->pos());
drawing = false;
}
}
void InkSpot::drawLineTo(const QPoint &endPoint)
{
QPainter painter(&pixmap);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::NoBrush);
QFile *stencilInput; // file for input, assumes a SQUARE RAW 8 bit grayscale image, no JPG no GIF, no size/format header, just 8 bit values in the file
char *brushPrototype; // raw brush prototype
uchar *brushData; // raw brush data
stencilInput = new QFile("C:/brush3.raw"); // open raw file
stencilInput->open(QIODevice::ReadOnly);
QDataStream in;
in.setDevice(stencilInput);
int size = stencilInput->size(); // set size to the length of the raw file
brushPrototype = new char[size]; // create the brush prototype array
in.readRawData(brushPrototype, size); // read the file into the prototype
brushData = new uchar[size]; // create the uchar array you need to construct QImage
for (int i = 0; i < size; ++i)
brushData[i] = (uchar)brushPrototype[i]; // copy the char to the uchar array
QImage test(brushData, 128, 128, QImage::Format_Indexed8); // create QImage from the brush data array
// 128x128 was my raw file, for any file size just use the square root of the size variable provided it is SQUARE
QImage test2(128, 128, QImage::Format_ARGB32);
QVector<QRgb> vectorColors(256); // create a color table for the image
for (int c = 0; c < 256; c++)
vectorColors[c] = qRgb(c, c, c);
test.setColorTable(vectorColors); // set the color table to the image
for (int iX = 0; iX < 128; ++iX) // fill all pixels with 255 0 0 (red) with random variations for OIL PAINT effect
// use your color of choice and remove random stuff for solid color
// the fourth parameter of setPixel is the ALPHA, use that to make your brush transparent by multiplying by opacity 0 to 1
{
for (int iY = 0; iY < 128; ++iY)
{
test2.setPixel(iX, iY, qRgba(255, 100, 100, (255-qGray(test.pixel(iX, iY)))*0.5));
}
}
// final convertions of the stencil and color brush
QPixmap testPixmap = QPixmap::fromImage(test2);
QPixmap testPixmap2 = QPixmap::fromImage(test);
painter.setBrush(Qt::NoBrush);
painter.setPen(Qt::NoPen);
// in a paint event you can test out both pixmaps
// QLineF line = QLineF(lastPoint, endPoint);
// float lineLength = line.length();
// qDebug() << line.length();
// line.setLength(100.01f);
// qDebug() << line.length();
QPainterPath path = QPainterPath(lastPoint);
path.lineTo(endPoint);
//qDebug() << path.currentPosition();
//qDebug() << path.length();
qreal length = path.length();
qreal pos = 0;
while (pos < length)
{
qreal percent = path.percentAtLength(pos);
painter.drawPixmap(path.pointAtPercent(percent).x() - 16, path.pointAtPercent(percent).y() - 16, 32, 32, testPixmap);
pos += spacing;
}
//painter.drawPixmap(line.p1().x() - 16, line.p1().y() - 16, 32, 32, testPixmap);
//delete all dynamically allocated objects with no parents
delete [] brushPrototype;
delete [] brushData;
delete stencilInput;
lastPoint = endPoint;
}
void InkSpot::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::NoBrush);
QRect rect = event->rect();
painter.drawPixmap(rect, pixmap, rect);
qDebug() << spacing;
update();
}
newdialog.h
#ifndef NEWDIALOG_H
#define NEWDIALOG_H
//#include "ui_newdialog.h"
#include "inkpuppet.h"
#include <QDialog>
namespace Ui {
class NewDialog;
}
class NewDialog : public QDialog
{
Q_OBJECT
public:
explicit NewDialog(QWidget *parent = 0);
~NewDialog();
InkPuppet *pointerToPuppet;
Ui::NewDialog *ui;
public slots:
//void createNew(InkPuppet *existingPuppet);
void createNew();
};
#endif // NEWDIALOG_H
newdialog.cpp
#include "newdialog.h"
#include "ui_newdialog.h"
#include "inkpuppet.h"
#include "ui_inkpuppet.h"
#include "inkspot.h"
#include <QDebug>
#include <QSignalMapper>
#include <QObject>
#include <QtOpenGL/QGLWidget>
NewDialog::NewDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::NewDialog)
{
ui->setupUi(this);
connect(ui->buttonBox, SIGNAL(accepted()), SLOT(createNew()));
//connect(ui->buttonBox, SIGNAL(accepted()), SLOT(createNew(InkPuppet*)));
}
void NewDialog::createNew()
{
InkSpot *ink;
ink = new InkSpot();
ink->newDialog = this;
pointerToPuppet->ui->canvas->addWidget(ink->widget);
//QSize size = pointerToPuppet->ui->canvas->sizeHint();
ink->widget->resize(ui->widthBox->value(), ui->heightBox->value());
pointerToPuppet->ui->scrollCanvasItems->resize(ui->widthBox->value(), ui->heightBox->value());
//pointerToPuppet->ui->canvas->setAlignment(ink->widget, Qt::AlignAbsolute);
ink->pixmap = QPixmap(QSize(ui->widthBox->value(), ui->heightBox->value()));
close();
}
NewDialog::~NewDialog()
{
delete ui;
}
main.cpp
#include "inkpuppet.h"
#include "inkspot.h"
#include "newdialog.h"
#include "aboutdialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
InkPuppet w;
w.show();
return a.exec();
}
You have circular dependencies. "inkpuppet.h" includes "inkspot.h", which includes "newdialog.h", which includes "inkpuppet.h". Use forward declarations instead, where you can.
You have circular includes, that are prevented by your header guardians. This means that in your newdialog.h the line #include "inkpuppet.h" does nothing, resulting in the InkPuppet class is not declared. You need to replace the include line by a forward declaration class InkPuppet; and don't forget to include the file in the cpp (in that case, you've got it already).
EDIT: You have to be careful with the namespaces as well, you've got all your classes in two namespaces (global and Ui).