draw in a QFrame on clicking a button. - c++

Say there is a QPushButton named "Draw", a QLineEdit and a QFrame. On clicking the button I want to take a number from QLineEdit and draw a circle in a QFrame. How can I do this? Please provide me with the code.
P.S. The problem is that draw methods of the QPainter should be called in drawEvent method.

If #Kaleb Pederson's answer is not enough for you then here's a complete solution for a simple set-up matching what you describe. Tested with Qt 4.5.2 on Linux. I had some spare time... ;)
main.cpp:
#include <QApplication>
#include "window.h"
int main( int argc, char** argv )
{
QApplication qapp( argc, argv );
Window w;
w.show();
return qapp.exec();
}
window.h
#pragma once
class QLineEdit;
class QPushButton;
#include <QWidget>
class Frame;
class Window : public QWidget
{
Q_OBJECT
public:
Window();
private slots:
void onButtonClicked();
private:
QLineEdit* m_lineEdit;
QPushButton* m_pushButton;
Frame* m_frame;
};
window.cpp:
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include "frame.h"
#include "window.h"
Window::Window()
: m_lineEdit ( new QLineEdit( this ) )
, m_pushButton( new QPushButton( tr( "Draw" ), this ) )
, m_frame ( new Frame( this ) )
{
connect( m_pushButton, SIGNAL( clicked() )
, SLOT( onButtonClicked() ) );
QHBoxLayout*const hLayout = new QHBoxLayout;
hLayout->addWidget( m_lineEdit );
hLayout->addWidget( m_pushButton );
QVBoxLayout*const vLayout = new QVBoxLayout( this );
vLayout->addLayout( hLayout );
m_frame->setFixedSize( 300, 400 );
vLayout->addWidget( m_frame );
setLayout( vLayout );
}
void Window::onButtonClicked()
{
const int r = m_lineEdit->text().toInt(); // r == 0 if invalid
m_frame->setCircleRadius( r );
m_frame->update();
}
frame.h:
#pragma once
#include <QFrame>
class Frame : public QFrame
{
Q_OBJECT
public:
Frame( QWidget* );
void setCircleRadius( int );
protected:
void paintEvent( QPaintEvent* );
private:
int m_radius;
};
frame.cpp:
#include <QPainter>
#include "frame.h"
Frame::Frame( QWidget* parent )
: QFrame( parent )
, m_radius( 0 )
{
setFrameStyle( QFrame::Box );
}
void Frame::setCircleRadius( int radius )
{
m_radius = radius;
}
void Frame::paintEvent( QPaintEvent* pe )
{
QFrame::paintEvent( pe );
if ( m_radius > 0 )
{
QPainter p( this );
p.drawEllipse( rect().center(), m_radius, m_radius );
}
}

If you want your frame to do the drawing, then it needs a way to know that it should draw something, so create a slot that will receive notification:
/* slot */ void drawCircle(QPoint origin, int radius) {
addCircle(origin, radius);
update(); // update the UI
}
void addCircle(QPoint origin, int radius) {
circleList.add(new Circle(origin,radius));
}
Then, your frame subclass you need to override paintEvent() to draw the circle:
void paintEvent(QPaintEvent *event) {
QFrame::paintEvent(event);
QPainter painter(this);
foreach (Circle c, circleList) { // understand foreach requirements
painter.drawEllipse(c.origin(), c.radius(), c.radius());
}
}
As long as the slot responding to the button's clicked() signal emits a signal that calls the drawCircle slot with the correct arguments everything should work correctly.

You don't draw diectly onto a frame.
Start here graphicsview, it looks complicated at first - but GUI program is a big leap when you first encounter it
In most GUIs (Qt, OpenGL etc) you build up a list of elements you want to draw in your program and store them somehow - then there is a draw() function that gets called when the computer needs to draw your picture - eg when it is moved or another window is moved in front of it. The OnDraw or OnRepaint etc function then gets called and you have to draw the list of objects.
Another way to do this is to draw them all to an image (QOimage or QPixmap) and copy that to the screen in OnDraw or OnRepaint - you might do this for a graphics package for example.

Related

How to fix: custom QGraphicsItem receiving mousePressEvent coordinates late/laggy?

I have a "standard" Qt5 QWidgets application, with a MainWindow that includes a QGraphicsView in the mainwindow.ui created in QtCreator. That QGraphicsView has its scene set to a simple subclass of QGraphicsScene, which has a big rectangle in the background that is a subclass of QGraphicsRectItem which reimplements the mousePressEvent() and mouseReleaseEvent() handlers of the QGraphicsRectItem. Running on Ubuntu 18.04, which shouldn't matter, but just incase...
Everything is working, except... the 2nd and later times I press the left (or any) mouse button, the coordinates reported in the mousePressEvent's QGraphicsSceneMouseEvent buttonDownScenePos are "stale" - the same as the previous mouse click, not the new location where the mouse is when the new click happened. The mouseReleaseEvent reports coordinates as expected.
Is there any way to get the buttonDownScenePos of the mousePressEvent to stay current with the actual position of the mouse when clicked, instead of the previous mouse location?
I feel like I have dealt with a similar issue in the past which had something to do with double-click processing, that the event is reported before it knows if a double-click has happened or not. In this instance, double-click events are not important, but it would be nice to be able to respond to the single click as soon as it happens, instead of waiting for the release event.
Relevant code:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
class Board;
class BoardScene;
#include <QMainWindow>
#include <QPointer>
#include "board.h"
#include "boardscene.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{ Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void drawBoard();
private:
Ui::MainWindow *ui;
QPointer<Board> board;
QPointer<BoardScene> boardScene;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
board = new Board( this );
boardScene = new BoardScene( board, this );
ui->boardView->setScene( boardScene );
ui->boardView->setDragMode( QGraphicsView::ScrollHandDrag );
ui->boardView->scale( 40.0, 40.0 );
drawBoard();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::drawBoard()
{ }
boardscene.h
#ifndef BOARDSCENE_H
#define BOARDSCENE_H
class Board;
#include <QGraphicsScene>
#include "board.h"
#include "boardrect.h"
class BoardScene : public QGraphicsScene
{ Q_OBJECT
public:
BoardScene( Board *pbp, QObject *parent = nullptr );
void drawGrid();
Board *bp;
QBrush backBrush,blackBrush,whiteBrush;
QPen linePen;
};
#endif // BOARDSCENE_H
boardscene.cpp
#include "boardscene.h"
#include <QGraphicsLineItem>
#include <QGraphicsRectItem>
BoardScene::BoardScene( Board *pbp, QObject *parent ) : QGraphicsScene ( parent )
{ bp = pbp;
backBrush = QBrush( QColor( 224,152, 64 ) );
blackBrush = QBrush( QColor( 0, 0, 0 ) );
whiteBrush = QBrush( QColor( 255,255,255 ) );
linePen = QPen ( QColor( 0, 0, 0 ) );
linePen.setWidth( 0 );
drawGrid();
}
void BoardScene::drawGrid()
{ QGraphicsLineItem *lip;
BoardRect *rip;
setBackgroundBrush( blackBrush );
rip = new BoardRect( QRectF( -2.0, -2.0, (qreal)(bp->Xsize +3), (qreal)(bp->Ysize + 3) ), nullptr );
rip->setBrush( backBrush );
rip->setPen( linePen );
addItem( rip );
for ( int x = 0; x < bp->Xsize; x++ )
{ lip = addLine( QLineF( (qreal)x, 0.0, (qreal)x, (qreal)(bp->Ysize - 1) ), linePen );
lip->setAcceptedMouseButtons( Qt::NoButton );
}
for ( int y = 0; y < bp->Ysize; y++ )
{ lip = addLine( QLineF( 0.0, (qreal)y, (qreal)(bp->Xsize - 1), (qreal)y ), linePen );
lip->setAcceptedMouseButtons( Qt::NoButton );
}
}
boardrect.h
#ifndef BOARDRECT_H
#define BOARDRECT_H
#include <QGraphicsRectItem>
#include <QGraphicsSceneMouseEvent>
class BoardRect : public QGraphicsRectItem
{
public:
BoardRect( const QRectF &rect, QGraphicsItem *parent = nullptr );
~BoardRect() {}
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};
#endif // BOARDRECT_H
boardrect.cpp
#include "boardrect.h"
BoardRect::BoardRect( const QRectF &rect, QGraphicsItem *parent ) : QGraphicsRectItem( rect, parent )
{}
void BoardRect::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ QString msg = QString("press %1 %2").arg(event->buttonDownScenePos(event->button()).rx())
.arg(event->buttonDownScenePos(event->button()).ry());
qDebug( qPrintable( msg ) );
QGraphicsRectItem::mousePressEvent(event);
event->accept();
}
void BoardRect::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ QString msg = QString("release %1 %2").arg(event->buttonDownScenePos(event->button()).rx())
.arg(event->buttonDownScenePos(event->button()).ry());
qDebug( qPrintable( msg ) );
QGraphicsRectItem::mousePressEvent(event);
event->accept();
}
On the first click after running, the reported coordinates agree well with the location on the grid where the mouse was clicked, both for press and release - they both show where the button went down.
However, on the 2nd and later clicks, the mousePressEvent reports the same coordinates as the previous mousePress and Release events, while the mouseReleaseEvent reports the coordinates where the mouse button "went down" in the current event.
One final bit of weirdness: when clicking left, then right, then left again, the coordinate reported by mousePressEvent for the 2nd left click is the previous left click coordinate, skipping over the right click coordinate to go back to where the mouse button went down on the last left click.
Any ideas? Thanks.
I have an app using the same components: a qgraphicsview and a qgraphicsscene composed by some number of qgraphicsitems. It is a virtual MIDI piano keyboard just in case you want to take a look to the code. In my case, all the qgraphicsitems (the piano keys) have setAcceptedMouseButtons(Qt::NoButton), and the mouse events are handled at the scene level instead of the graphics item. I've never observed a problem like yours.
QGraphicsSceneMouseEvent::buttonDownPos(Qt::MouseButton button)
Returns the mouse cursor position in item coordinates where the
specified button was clicked.
It returns the coordinates from the graphics item you are clicking on (as the documentation says). Maybe you just click in the same spot?
If you want the scene position, just use mapToScene or QGraphicsSceneMouseEvent::buttonDownScenePos(Qt::MouseButton button) or event->scenePos().
PS.
and use QPointF::x() and QPointF::y() instead of rx() and ry(). You don't need a reference and manipulate the position.

QWidget do not trigger QEvent::MouseMove when entered with Pressed button

In Qt with C++, I created a window with a small QWidget inside.
The small QWidget show a message every time QEvent::Enter, QEvent::Leave or QEvent::MouseMove is triggered.
When any mouse button is pressed (and holded) outside of the small QWidget, and the mouse is moved on the top of this small QWidget (While holding), QEvent::MouseMove is not triggered for this small QWidget. Additionally, QEvent::Enter is postponed to after the mouse button is released.
In the reverse situation: when the mouse is pressed on the small QWidget (and holded), and then the mouse is moved outside, the QEvent::Leave is postponed to after the mouse button is released.
IS there any solution to retrieve QEvent::MouseMove all the time, even when the mouse button is holded?
Additional data: Yes, setMouseTracking(true) is set.
Testing example:
Widget:
#ifndef MYWIDGET_HPP
#define MYWIDGET_HPP
#include <QWidget>
#include <QStyleOption>
#include <QPainter>
#include <QEvent>
#include <QDebug>
class MyWidget: public QWidget
{
Q_OBJECT
public:
MyWidget( QWidget* parent=nullptr ): QWidget(parent)
{
setMouseTracking(true);
}
protected:
// Paint for styling
void paintEvent(QPaintEvent *)
{
// Needed to allow stylesheet.
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
// Show Enter and Leave event for debugging purpose
bool event( QEvent *e)
{
static int counting=0;
if (e->type() ==QEvent::Enter)
{
qDebug() << counting++ << " Enter: " << this->objectName();
}
if (e->type() ==QEvent::Leave)
{
qDebug() << counting++ << " Leave: " << this->objectName();
}
if (e->type() ==QEvent::MouseMove)
{
qDebug() << counting++ << " Move: " << this->objectName();
}
return QWidget::event(e);
}
};
#endif // MYWIDGET_HPP
Main
#include <QApplication>
#include <QDebug>
#include <QWidget>
#include <QTimer>
#include "Testing.hpp"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Create a main window
QWidget main;
main.setWindowTitle("Cursor blocked for 5s - wait and see");
main.resize(500, 200);
main.move(200, 200);
// Create a MyWidget
MyWidget sub(&main);
sub.setObjectName("sub");
sub.resize(50, 50);
sub.move(50, 50);
// Style the button with a hover
main.setStyleSheet
(
"QWidget#sub{background-color: rgba(0,0,128,0.5);}"
"QWidget#sub:hover{background-color: rgba(128,0,0,0.5);}"
);
// Show the window
main.show();
return a.exec();
}
Project
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
SOURCES +=\
main.cpp
HEADERS +=\
Testing.hpp
RESOURCES +=\
CONFIG += c++11 -Wall
TARGET = Testing
TEMPLATE = app
It is standard behavior. When you press mouse button, widget begin to grab it (make a call of QWidget::grabMouse). I think that you should redesign your behavior, or explain some real use-cases, when you need to track mouse globally.
If you really need to track mouse, you may use event filters.
Pseudo-code (without checks):
QWidget *otherWidget = /*...*/;
QWidget *myWidget = /*...*/;
otherWidget->installEventFilter( myWidget );
// you need to install filter on each widget,
// that you want to track.
// Care with performance
MyWidget : QWidget
{
void handleMouseMove( QPoint pos ) { /*...you code...*/ }
void mouseMove( QMouseEvent *e ) override;
{
handleMouseMove( e->pos() );
QWidget::mouseMove( e );
}
bool eventFilter( QObject *obj, QEvent *e )
{
auto srcWidget = qobject_cast< QWidget * >( obj );
switch ( e->type() )
{
case QEvent::MouseMove:
{
auto me = static_cast< QMouseEvent * >( e );
auto globalPos = srcWidget->mapToGlobal( me->pos() );
auto localPos = this->mapFromGlobal( globalPos ); // Possible, you need to invalidate that poing belongs to widget
handleMouseMove( localPos );
}
break;
};
return QWidget::eventFilter( obj, e );
}
};

Fading away widget in QT C++

I want to make a simple QWidget which is a simple rectangle fade away. The main problem is that the paint event paint at the same place every time in fact making the effect opposite, it make the colour stronger. Is there any way of achieving this functionality? Could you maybe provide some simple example?
My code:
`
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTimer>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
void paintEvent(QPaintEvent*);
~Widget();
private:
Ui::Widget *ui;
int alfa;
int i;
QTimer time;
};
#endif // WIDGET_H
`
and the cpp:
#include "widget.h"
#include "ui_widget.h"
#include <QColor>
#include <QPainter>
#include <QBrush>
#include <QTimer>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent,Qt::Popup | Qt::FramelessWindowHint),
ui(new Ui::Widget),
time()
{
ui->setupUi(this);
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_PaintOnScreen);
time.setInterval(500);
time.start();
connect(&time,SIGNAL(timeout()),this,SLOT(update()));
alfa=100;
i=0;
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int rectBase = height();
QColor c(255,0,255);
alfa=alfa-(i*10);
c.setAlpha(alfa);
qDebug()<<c.alpha();
i++;
painter.setBrush(QBrush(c));
painter.drawRect(0, 0, width(),height());
}
Widget::~Widget()
{
delete ui;
}
You shouldn't rely on QWidget::paintEvent() to change your alpha level, since it can be called less or more than you want (multiple update() calls may result in only one paintEvent() and paintEvent() may be called when you don't expect it).
So a more reliable way to get to the result, is have a separate slot where you decrease the alpha level and then call update(). Your class definition might look like this:
class Widget : public QWidget
{
Q_OBJECT
public:
Widget( QWidget * inParent );
private:
void paintEvent(QPaintEvent *);
private slots:
void animate();
private:
QTimer * mTimer;
int mAlpha;
};
And the declaration:
Widget::Widget( QWidget * inParent )
:
QWidget( inParent ),
mTimer( new QTimer( this ) ),
mAlpha( 255 )
{
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_PaintOnScreen);
mTimer->setInterval( 40 );
mTimer->setSingleShot( false );
connect( mTimer, SIGNAL(timeout()), this, SLOT(animate()) );
mTimer->start();
}
void
Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush( QColor(255,0,255,mAlpha ) );
painter.drawRect(rect());
}
void
Widget::animate()
{
if ( mAlpha > 0 )
{
mAlpha -= 3;
}
else
{
mTimer->stop();
}
update();
}
Notice that I did decrease the interval of the timer. You only called an update() every half a second. That typically does not result in a smooth animation.
I get a warning with this code on Kubuntu Linux, under Qt5:
QWidget::paintEngine: should no longer be called
The originating line is in qWarning("QWidget::paintEngine: Should no longer be called");, in src/widgets/kernel/qwidget_qpa.cpp and discussed a bit in this ticket:
https://qt.gitorious.org/qt/qtbase-harmattan/commit/3037525
You can get the warning to stop by removing the setAttribute(Qt::WA_PaintOnScreen);, so I did that. After taking that line out, it works for me--although your subtraction model is strange. You are modifying the alpha as well as changing the subtraction value on each iteration; you probably didn't intend both. So either change it to:
QColor c (255, 0, 255);
alfa = alfa - 10;
if (alfa >= 0) {
c.setAlpha(alfa);
} else {
time.stop();
}
...or:
QColor c(255,0,255);
if (alfa - i * 10 >= 0) {
c.setAlpha(alfa - i * 10);
i++;
} else {
time.stop();
}
Etc. (See also #PrisonMonkeys note on your timer not necessarily being the only source of update() calls.) Regarding getting these warnings to be more vocal so you don't miss them, you might look at The Essential Noisy Debug Hook For Qt, which I should update.
If with the change, an alpha blended window doesn't work on your platform at all, you should mention explicitly what your circumstance is...as it is working for me.

QPixmap on QLabel doesn't show correctly

I am trying to draw some shape with QPainter class and save it to disk. As far as I know the easiest way is to use QPainter to draw into a QPixmap, visualize in the pixmap though a QLabel, and use QPixmap::save.
But when I run this test I see only a little black box inside the QWidget.
MyWidget::MyWidget()
{
std::cout << "MyWidget > ." << std::endl;
l = new QLabel();
l->setParent(this);
pixmap = new QPixmap(460, 480);
painter = new QPainter(pixmap);
}
MyWidget::~MyWidget()
{
delete pixmap;
delete painter;
}
void MyWidget::paintEvent(QPaintEvent *event)
{
std::cout << "dudee" << std::endl;
painter->begin(pixmap);
painter->drawLine(1,1,100,100);
QPen myPen(Qt::black, 2, Qt::SolidLine);
painter->setPen(myPen);
painter->drawLine(100,100,100,1);
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setPen(QPen(Qt::black, 3, Qt::DashDotLine, Qt::RoundCap));
painter->setBrush(QBrush(Qt::green, Qt::SolidPattern));
painter->drawEllipse(200, 80, 400, 240);
painter->end();
l->setPixmap(*pixmap);
}
I have tried to add some l->update() but it doesn't change anything..
EDIT:
It should be an animation. I get the animation work through a QTimer that call every n msec the function for draw (not the paintEvent as the answer suggest)
You need instance of QPainter only during painting something. You don't need to keep it as class member.
Pixmap may be declared as class member, not as pointer.
Paint should be done once. It is bad idea to draw you external pixmap inside paintEvent, because you don't know, when exactly paintEvent will be called (and how much times).
You must not set pixmap for a label inside paint event, because call of l->setPixmap forces your widget to update => you will get infinite loop of draw->set->update->draw...
Solution:
Create somewhere a pixmap and paint on it necessary content.
Set content to a label, when it necessary (for example, after drawing).
Do not call update() - it will be called automatically, when you will set pixmap to label.
EDITED code:
Simple class for edited question:
AnimationSample.h
#ifndef ANIMATIONSAMPLE_H
#define ANIMATIONSAMPLE_H
#include <QWidget>
#include <QPixmap>
#include <QLabel>
#include <QPointer>
#include <QTimer>
class AnimationSample
: public QWidget
{
Q_OBJECT
public:
AnimationSample( QWidget *parent = NULL );
~AnimationSample();
private slots:
void onTick();
private:
QPointer< QLabel > m_label;
QPointer< QTimer > m_timer;
int m_salt;
};
#endif // ANIMATIONSAMPLE_H
AnimationSample.cpp
#include "AnimationSample.h"
#include <QPixmap>
#include <QPainter>
AnimationSample::AnimationSample( QWidget *parent )
: QWidget( parent )
, m_salt( 1 )
{
m_label = new QLabel( this );
m_label->setFixedSize( 100, 100 );
m_timer = new QTimer( this );
connect( m_timer, SIGNAL( timeout() ), SLOT( onTick() ) );
m_timer->start( 250 );
}
AnimationSample::~AnimationSample()
{
}
void AnimationSample::onTick()
{
QPixmap pic( 100, 100 );
QPainter p( &pic );
QPen myPen( Qt::black, 2, Qt::SolidLine );
p.setPen( myPen );
p.drawLine( 0, 0, m_salt, m_salt );
m_salt = (m_salt + 1) % 100;
m_label->setPixmap( pic );
}

How do I get the currently visible text from a QTextEdit or QPlainTextEdit widget?

It seems like this would be a common thing to do, but I can't find how.
I have a QTextEdit or QPlainTextEdit widget with a bunch of text. Enough that scrolling is necessary.
I want another widget to give some information about the currently visible text. To do this, I need to know
when the visible text changes
what's the text?
I see that QPlainTextEdit has the method firstVisibleBlock, but it's protected. This tells me that it's not really something I should be using in my application. I wouldn't otherwise need to subclass from the edit window.
I also see that there's the signal updateRequest but it's not clear what I do with the QRect.
How do I do it or where do I find a hint?
I've written a minimal program that as two QTextEdit fields. In the left field you write and the text you are writing is shown in the second text edit too. You get the text of a QTextEdit by using toPlainText() and the signal is textChanged().
I've tested it and what you write in m_pEdit_0 is shown in "real-time" in m_pEdit_1.
main_window.hpp
#ifndef __MAIN_WINDOW_H__
#define __MAIN_WINDOW_H__
#include <QtGui/QtGui>
#include <QtGui/QMainWindow>
#include <QtGui/QApplication>
class main_window : public QMainWindow
{
Q_OBJECT
public:
main_window( QWidget* pParent = 0 );
~main_window();
public Q_SLOTS:
void on_edit_0_text_changed();
private:
QHBoxLayout* m_pLayout;
QTextEdit* m_pEdit_0;
QTextEdit* m_pEdit_1;
};
#endif // !__MAIN_WINDOW_H__
main_window.cpp
#include "main_window.hpp"
main_window::main_window( QWidget *pParent ) : QMainWindow( pParent )
{
m_pEdit_0 = new QTextEdit( this );
m_pEdit_1 = new QTextEdit( this );
connect( m_pEdit_0, SIGNAL( textChanged() ), this, SLOT( on_edit_0_text_changed() ) );
m_pLayout = new QHBoxLayout;
m_pLayout->addWidget( m_pEdit_0 );
m_pLayout->addWidget( m_pEdit_1 );
QWidget* central_widget = new QWidget( this );
central_widget->setLayout( m_pLayout );
setCentralWidget( central_widget );
}
main_window::~main_window()
{
}
void main_window::on_edit_0_text_changed()
{
m_pEdit_1->setText( m_pEdit_0->toPlainText() );
}
main.cpp
#include "main_window.hpp"
int main( int argc, char* argv[] )
{
QApplication a(argc, argv);
main_window mw;
mw.show();
return a.exec();
}
Edit:
This would work too, but would lack in performance for huge documents:
void main_window::on_edit_0_text_changed()
{
QStringList text_in_lines = m_pEdit_0->toPlainText().split( "\n" );
m_pEdit_1->clear();
for( int i = 0; i < text_in_lines.count(); i++ )
{
m_pEdit_1->append( text_in_lines.at( i ) );
}
}