I would like to paint a QPolygon on my Window and be able to use it as a QPushbutton.
Is there any way to do this?
(most preferably without using QMousePressEvent to check the position of the mouse with the position of the polygon)
After the advice of Ton:
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
qv_point = {QPoint(10,20), QPoint(20,30), QPoint(50,30)};
ui->pushButton = new QPolygonPushButton(qv_point);
ui->setupUi(this);
ui->pushButton->update();
}
MainWindow::~MainWindow()
{
delete ui;
}
qpolygonpusbutton.cpp:
#include "qpolygonpushbutton.h"
QPolygonPushButton::QPolygonPushButton(QVector<QPoint> qv_points)
{
this->polygon << qv_points;
}
void QPolygonPushButton::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.setViewport(e->rect());
painter.setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter.drawPolygon(this->polygon);
}
This can be done by declaring your own push button type, something like QPolygonPushButton that derives from QPushButton, for which you then reimplement its paintEvent member function.
Something along the following lines (not tested):
class QPolygonPushButton : public QPushButton
{
public:
using QPushButton::QPushButton;
private:
void paintEvent(QPaintEvent* e) override
{
QPainter painter(this);
painter.setViewport(e->rect());
painter.drawPolygon(...);
}
};
Update; fully working example. It uses a rectangle instead of a polygon but other than that you will get the idea. The button initially is a red rectangle, clicking it will change its color to blue.
#include <QtCore/QObject>
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
#include <QtGui/QPainter>
#include <QtGui/QPushButton>
namespace
{
QColor buttonColor{Qt::red};
}
class QRectButton : public QPushButton
{
public:
using QPushButton::QPushButton;
void paintEvent(QPaintEvent* e) override
{
QPainter painter(this);
painter.setPen(buttonColor);
painter.setBrush(buttonColor);
painter.drawRect(painter.window());
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow() : QMainWindow(nullptr)
{
QPushButton* button{new QRectButton(this)};
QObject::connect(button, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
}
private slots:
void onButtonClicked()
{
buttonColor = Qt::blue;
update();
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
#include "moc_polygon_button.cpp"
Related
In normal screen mode, Qt widgets receive mouse events immediately after creation. In full-screen mode on macOS, however, it takes a while until the widget starts receiving those events. From my tests, it takes ~700ms on average until a widget receives its first mouse event versus ~30ms in normal screen mode. Why does it take so long for mouse events to stream in when using full-screen mode? Is there a way to force Qt to receive those events earlier? See my test in the GIF animation below.
The source code for my test follows below.
/**
* main.cpp
*/
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return QApplication::exec();
}
/**
* mainwindow.h
*/
#pragma once
#include "popupwindow.h"
#include <QWidget>
#include <QPushButton>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private slots:
void handleFullScreenButton();
void handleNormalScreenButton();
private:
PopupWindow* m_fullScreenWindow;
QPushButton* m_fullScreenButton;
QPushButton* m_normalScreenButton;
PopupWindow* m_normalScreenWindow;
};
/**
* popupwindow.h
*/
#pragma once
#include <QWidget>
#include <QLabel>
class PopupWindow : public QWidget
{
Q_OBJECT
public:
explicit PopupWindow(QWidget* parent = nullptr);
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
private:
void showText(const QString &text);
QLabel* m_text;
qint64 m_creationTimestamp;
bool m_eventReceived;
};
/**
* mainwindow.cpp
*/
#include "mainwindow.h"
#include <QDebug>
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
: m_normalScreenWindow(nullptr)
, m_fullScreenWindow(nullptr)
{
auto *layout = new QVBoxLayout(this);
m_normalScreenButton = new QPushButton("Popup screen");
m_fullScreenButton = new QPushButton("Popup full screen");
connect(m_normalScreenButton, &QPushButton::released, this, &MainWindow::handleNormalScreenButton);
connect(m_fullScreenButton, &QPushButton::released, this, &MainWindow::handleFullScreenButton);
layout->addWidget(m_normalScreenButton);
layout->addWidget(m_fullScreenButton);
}
void MainWindow::handleNormalScreenButton() {
m_normalScreenWindow = new PopupWindow(this);
m_normalScreenWindow->show();
m_normalScreenWindow->activateWindow();
m_normalScreenWindow->raise();
}
void MainWindow::handleFullScreenButton() {
m_fullScreenWindow = new PopupWindow(this);
m_fullScreenWindow->showFullScreen();
m_fullScreenWindow->activateWindow();
m_fullScreenWindow->raise();
}
/**
* popupwindow.cpp
*/
#include "popupwindow.h"
#include <QDateTime>
#include <QDebug>
#include <QHBoxLayout>
PopupWindow::PopupWindow(QWidget *parent)
: m_creationTimestamp(QDateTime::currentMSecsSinceEpoch())
, m_eventReceived(false)
, m_text(nullptr)
{
setAttribute(Qt::WA_DeleteOnClose);
setMouseTracking(true);
}
void PopupWindow::mouseMoveEvent(QMouseEvent *event) {
if (m_eventReceived) {
return;
}
auto deltaTimeMs = QDateTime::currentMSecsSinceEpoch() - m_creationTimestamp;
showText(QString("First mouse event received after %1 ms.").arg(deltaTimeMs));
m_eventReceived = true;
}
void PopupWindow::mousePressEvent(QMouseEvent *event) {
showNormal();
close();
}
void PopupWindow::showText(const QString &text) {
m_text = new QLabel(text);
m_text->setStyleSheet("font: 26pt;");
auto *layout = new QVBoxLayout(this);
layout->addWidget(m_text, Qt::AlignCenter);
}
I'm working in ubuntu kde 20.04, qt5.15
I my purpose was to create a QPushButton that change his color when he got clicked, then I created a new derived class for doing this (Facelet), it works but the colors I got are not those I was assuming to get.
Facelet.h
#ifndef FACELET_H
#define FACELET_H
#include <QPushButton>
class Facelet : public QPushButton
{
Q_OBJECT
public:
explicit Facelet(QWidget * parent = nullptr);
explicit Facelet(int color, QWidget *pareny = nullptr);
void reset();
static QString colors[6];
private slots:
void __change_color();
private:
int _ColorIndex;
};
#endif // FACELET_H
Facelet.cpp
#include "Facelet.h"
QString Facelet::colors[6] = { "background-color: yellow;", "background-color: red;", "background-color: green;", "background-color: rgb(255, 130, 50);", "background-color: blue;", "background-color: white;" };
enum { rxyellow, rxred, rxgreen, rxorange, rxblue, rxwhite };
//public
Facelet::Facelet(QWidget *parent) :
QPushButton(parent),
_ColorIndex(-1)
{
this->resize(75, 75);
this->setStyleSheet("background-color: gray");
connect(this, SIGNAL(clicked()), SLOT(__change_color()));
}
Facelet::Facelet(int color, QWidget* parent) :
QPushButton(parent),
_ColorIndex(color)
{
this->resize(75, 75);
this->setStyleSheet(colors[_ColorIndex]);
connect(this, SIGNAL(clicked()), SLOT(__change_color()));
}
void Facelet::reset() {
this->setStyleSheet("background-color: gray");
}
//private
void Facelet::__change_color() {
_ColorIndex = (_ColorIndex >= 5 ) ? 0 : (_ColorIndex + 1);
this->setStyleSheet(colors[_ColorIndex]);
}
And here my main.cpp
#include <QApplication>
#include <QMainWindow>
#include "Facelet.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
Facelet f;
w.setCentralWidget(&f);
w.show();
return a.exec();
}
See? The screen is faded, I want a uniform strong color. What's wrong with my code?
To correct that I found two solution via reimplementation od paintEvent method.
first
void Facelet::paintEvent(QPaintEvent*) {
QPainter p(this);
p.setOpacity(1.0);
}
the first one is pretty easy, reading some topic I found out that a QWidget to have a setStyleSheet(QString) methods working properly need the following line in the paintEvent(QPaintEvent*) method as the official documentation says
void Facelet::paintEvent(QPaintEvent *) {
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
I'm working on an application where I need to be able to draw a line between two QWidget objects. I have tried quite a few things, but my current attempt (which I think is in the right direction I just think I'm missing something) is to have the containing widget (which I called DrawWidget and which holds the QGridLayout that the QWidget objects are added to) override the paintEvent method and call the QPainter::drawLine() function.
The issues I'm having are that:
No matter how I try to get the position of the widgets, the endpoints of the line are always in the wrong place
Whenever I try to draw a second line, the first line that I drew gets erased.
Here is the paintEvent function of the containing widget:
void paintEvent(QPaintEvent *)
{
if (!drewSinceUpdate){
drewSinceUpdate = true;
QPainter painter(this);
painter.setPen(QPen(Qt::black));
painter.drawLine(start->geometry().center(), end->geometry().center());
}
}
I have tried many different ways to get the correct position of the widgets in the last line of paintEvent, which I will post some of the ways (I can't remember all of them):
painter.drawLine(start->pos(), end->pos());
painter.drawLine(start->mapToGlobal(start->geometry().center()), end->mapToGlobal(end->geometry().center()));
painter.drawLine(this->mapToGlobal(start->geometry().center()), this->mapToGlobal(end->geometry().center()));
painter.drawLine(start->mapTo(this, start->pos()), end->mapTo(this, end->pos()));
painter.drawLine(this->mapFrom(start, start->pos()), this->mapFrom(end, end->pos()));
And just to make my question clear, here is an example of what I am looking for, taken from QT Diagram Scene Example:
But this is what I end up getting:
Thank you for any help you can provide.
NOTE:
-start and end are both QWidget objects which I passed in using another method
-The hierarchy relevant to DrawWidget is:
QMainWindow
->QScrollArea
->DrawWidget
->QGridLayout
->Items <-- These are the things I want to connect
EDIT: To make a Complete and Verifiable example, here is the entirety of the relevant code.
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QScrollBar>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
// Setting up the relevant hierarchy
ui->setupUi(this);
scrollArea = new QScrollArea();
setCentralWidget(scrollArea);
drawWidget = new DrawWidget();
gridLayout = new QGridLayout();
gridLayout->setSpacing(300);
drawWidget->setLayout(gridLayout);
scrollArea->setWidget(drawWidget);
scrollArea->setWidgetResizable(true);
AddItemSlot();
QApplication::connect(scrollArea->horizontalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(scrollHorizontal()));
}
// This is just creating a single one of the example widgets which I want to connect
QWidget* MainWindow::CreateNewItem(){
QWidget* itemWidget = new QWidget();
itemWidget->setStyleSheet("background-color: lightgray");
QHBoxLayout* singleItemLayout = new QHBoxLayout();
itemWidget->setLayout(singleItemLayout);
QTextEdit* textEdit = new QTextEdit(std::to_string(counter++).c_str());
textEdit->setStyleSheet("background-color:white;");
singleItemLayout->addWidget(textEdit);
QVBoxLayout* rightSidePanel = new QVBoxLayout();
rightSidePanel->setAlignment(Qt::AlignTop);
QPushButton* button1 = new QPushButton("Top Button");
QApplication::connect(button1, SIGNAL(clicked(bool)), this, SLOT(AddItemSlot()));
rightSidePanel->addWidget(button1);
QWidget* rightPanelWidget = new QWidget();
rightSidePanel->setMargin(0);
rightPanelWidget->setLayout(rightSidePanel);
singleItemLayout->addWidget(rightPanelWidget);
itemWidget->setLayout(singleItemLayout);
itemWidget->setMinimumWidth(400);
itemWidget->setFixedSize(400,200);
return itemWidget;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::scrollHorizontal()
{
scrollArea->ensureWidgetVisible(noteItems.back());
}
void MainWindow::AddItemSlot()
{
QWidget* w = CreateNewItem();
gridLayout->addWidget(w,currRow, currCol++);
if (!noteItems.empty()){
drawWidget->updateEndpoints(noteItems.back(), w);
}
noteItems.push_back(w);
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QGridLayout>
#include <QWidget>
#include <QMainWindow>
#include <QScrollArea>
#include <drawwidget.h>
#include "drawscrollarea.h"
#include <vector>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void scrollHorizontal();
void AddItemSlot();
private:
Ui::MainWindow *ui;
QWidget* CreateNewItem();
int counter = 0, currCol = 0, currRow = 0;
std::vector<QWidget*> noteItems;
QScrollArea* scrollArea;
DrawWidget* drawWidget;
QGridLayout* gridLayout;
};
#endif // MAINWINDOW_H
DrawWidget.cpp:
#include "drawwidget.h"
#include <QDebug>
#include <QRect>
DrawWidget::DrawWidget(QWidget *parent) : QWidget(parent)
{
}
void DrawWidget::paintEvent(QPaintEvent *)
{
if (!drewSinceUpdate){
drewSinceUpdate = true;
QPainter painter(this);
painter.setPen(QPen(Qt::black));
for (ConnectedPair pair : items){
const QWidget* from = pair.from;
const QWidget* to =pair.to;
QPoint start = from->mapToGlobal(from->rect().topRight() + QPoint(0, from->height()/2));
QPoint end = to->mapToGlobal(to->rect().topLeft() + QPoint(0, to->height()/2));
painter.drawLine(mapFromGlobal(start), mapFromGlobal(end));
}
}
}
void DrawWidget::updateEndpoints(QWidget* startIn, QWidget* endIn){
drewSinceUpdate = false;
items.push_back(ConnectedPair{startIn, endIn});
}
DrawWidget.h
#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H
#include <QWidget>
#include <QPainter>
#include <QtCore>
#include <vector>
class DrawWidget : public QWidget
{
Q_OBJECT
public:
explicit DrawWidget(QWidget *parent = nullptr);
void updateEndpoints(QWidget* startIn, QWidget* endIn);
virtual void paintEvent(QPaintEvent *);
signals:
private:
struct ConnectedPair {
const QWidget* from;
const QWidget* to;
};
std::vector<ConnectedPair> items;
bool drewSinceUpdate = true;
};
#endif // DRAWWIDGET_H
For this case we use the function mapToGlobal() and mapfromGlobal(), since pos() returns a position with respect to the parent and this can cause problems if the widget has different parents.
drawwidget.h
#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H
#include <QWidget>
class DrawWidget : public QWidget
{
Q_OBJECT
public:
explicit DrawWidget(QWidget *parent = nullptr);
void addWidgets(const QWidget *from, const QWidget *to);
protected:
void paintEvent(QPaintEvent *);
private:
struct WidgetsConnected {
const QWidget* from;
const QWidget* to;
};
QList<WidgetsConnected> list;
};
#endif // DRAWWIDGET_H
drawwidget.cpp
#include "drawwidget.h"
#include <QPainter>
DrawWidget::DrawWidget(QWidget *parent) : QWidget(parent)
{
}
void DrawWidget::addWidgets(const QWidget * from, const QWidget * to)
{
list.append(WidgetsConnected{from , to});
update();
}
void DrawWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
for(const WidgetsConnected el: list){
const QWidget* from = el.from;
const QWidget* to = el.to;
QPoint start = from->mapToGlobal(from->rect().topRight() + QPoint(0, from->height()/2));
QPoint end = to->mapToGlobal(to->rect().topLeft() + QPoint(0, to->height()/2));
painter.drawLine(mapFromGlobal(start), mapFromGlobal(end));
}
}
The complete example can be found here.
I am trying to arrange my subWindows in the QMdiArea vertically. I saw lot of examples online and they all were doing the same thing as I am doing here.
I have two textEdits which needs to be tiled vertically both covering half of the screen. So in the constructor of the MainWindow I add the two textEdits as subWindow to the qMdiArea and then find the height and width of the qMdiArea divide the height by 2 and resize the subWindow. Please see the code below.
My mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->showMaximized();
qMdiArea = new QMdiArea();
qTextEdit1 = new QTextEdit();
qTextEdit2 = new QTextEdit();
setCentralWidget(qMdiArea);
qMdiArea->adjustSize();
qMdiArea->addSubWindow(qTextEdit1);
qMdiArea->addSubWindow(qTextEdit2);
QPoint position(0, 0);
foreach (QMdiSubWindow *window, qMdiArea->subWindowList())
{
QRect rect(0, 0, qMdiArea->width(), qMdiArea->height() / qMdiArea->subWindowList().count());
window->setGeometry(rect);
window->move(position);
position.setY(position.y() + window->height());
}
}
MainWindow::~MainWindow()
{
delete ui;
}
My window.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMdiArea>
#include <QTextEdit>
#include <QPoint>
#include <QMdiSubWindow>
#include <QRect>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QMdiArea *qMdiArea;
QTextEdit *qTextEdit1;
QTextEdit *qTextEdit2;
};
#endif // MAINWINDOW_H
and my Main File :
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
But its not happening as expected. The window just occupy a part of the screen though they are tiled vertically. My screen resolution is 1920x1200
The height() and width() of mdiArea are invalid at that stage, because the widget hasn't been exposed/shown yet. Calling show() only schedules a widget for display, the act of sizing it and showing it on screen happens later when the control has returned to the event loop.
As a solution, you can override the resizeEvent handler. Once you do, your project will work again:
Definition in mainwindow.h:
virtual void resizeEvent(QResizeEvent *ev) override;
Implementation in mainwindow.cpp:
void MainWindow::resizeEvent(QResizeEvent *ev)
{
Q_UNUSED(ev)
QPoint position(0, 0);
foreach (QMdiSubWindow *window, qMdiArea->subWindowList())
{
QRect rect(0, 0, qMdiArea->contentsRect().width(), qMdiArea->contentsRect().height() / qMdiArea->subWindowList().count());
window->setGeometry(rect);
window->move(position);
position.setY(position.y() + window->height());
}
}
Also it seems that you don't really need to have this->showMaximized(); call inside MainWindow's constructor. You can call it from main.cpp, for example.
I want to update text in a label in a first window from a second window where is a line edit to write some text. This text should be dispaly in first window.
I spend a week for it.
A famous connect doesn't work.
Is somebody who correct below code and explain how connect should work?
I use Qt in version 5.1.1
firstwindow.h
#ifndef FIRSTWINDOW_H
#define FIRSTWINDOW_H
#include <QMainWindow>
#include "secondwindow.h"
namespace Ui {
class Firstwindow;
}
class Firstwindow : public QMainWindow
{
Q_OBJECT
public:
explicit Firstwindow(QWidget *parent = 0);
~Firstwindow();
public slots:
void addEntry();
private slots:
void on_pushButton_clicked();
private:
Ui::Firstwindow *ui;
Secondwindow *asecondwindow;
Secondwindow *absecondwindow;
Secondwindow *abcsecondwindow;
};
#endif // FIRSTWINDOW_H
secondwindow.h
#ifndef SECONDWINDOW_H
#define SECONDWINDOW_H
#include <QDialog>
#include <QtWidgets>
namespace Ui {
class Secondwindow;
}
class Secondwindow : public QDialog
{
Q_OBJECT
public:
explicit Secondwindow(QWidget *parent = 0);
~Secondwindow();
QLineEdit *lineEdit;
private slots:
void on_pushButton_clicked();
private:
Ui::Secondwindow *ui;
QPushButton *pushButton;
};
#endif // SECONDWINDOW_H
main.cpp
#include "firstwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Firstwindow w;
w.show();
return a.exec();
}
firstwindow.cpp
#include "firstwindow.h"
#include "ui_firstwindow.h"
#include <QtCore>
#include <QtGui>
#include <QtWidgets>
Firstwindow::Firstwindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Firstwindow)
{
ui->setupUi(this);
asecondwindow = new Secondwindow();
QObject::connect(asecondwindow->lineEdit,SIGNAL(textChanged()),this, SLOT(addEntry()));
}
Firstwindow::~Firstwindow()
{
delete ui;
delete asecondwindow;
delete absecondwindow;
delete abcsecondwindow;
}
void Firstwindow::on_pushButton_clicked()
{
absecondwindow = new Secondwindow;
absecondwindow->exec();
}
void Firstwindow::addEntry()
{
abcsecondwindow = new Secondwindow;
if (abcsecondwindow->exec()) {
QString name = abcsecondwindow->lineEdit->text();
ui->label->setText(name);
}
}
secondwindow.cpp
#include "secondwindow.h"
#include "ui_secondwindow.h"
#include <QDialog>
Secondwindow::Secondwindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::Secondwindow)
{
ui->setupUi(this);
}
Secondwindow::~Secondwindow()
{
delete ui;
}
void Secondwindow::on_pushButton_clicked()
{
// emit ui->lineEdit->textChanged();
QDialog::accept();
}
I see the following issues:
QLineEdit does not have a signal textChanged(). It should be textChanged(const QString &) instead. So you have to install your connection like:
QObject::connect(asecondwindow->lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(addEntry(const QString &)));
Please note that I changed the Firstwindow::addEntry() slot to Firstwindow::addEntry(const QString &) to match the signal's signature.
I cannot find when and where your QLineEdit member variable of the Secondwindow class is created.
There is a fundamental design problem with what you're doing. There's no need to expose the second window's internal properties to the first window. Just listen for changes within the second window and emit a signal whenever it changes. Then the first window can just listen to the changes on the second window.
Here's a full example showing what I mean. main.cpp:
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QMainWindow>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
class SecondWindow : public QDialog {
Q_OBJECT
public:
SecondWindow(QMainWindow *parent = 0) : QDialog(parent) {
QLineEdit *edit = new QLineEdit;
QPushButton *close = new QPushButton(QStringLiteral("close"));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(edit);
layout->addWidget(close);
setLayout(layout);
connect(edit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
connect(close, SIGNAL(clicked()), this, SLOT(close()));
}
signals:
void textChanged(const QString &text);
};
class FirstWindow : public QMainWindow {
Q_OBJECT
public:
FirstWindow(QMainWindow *parent = 0) : QMainWindow(parent) {
QWidget *central = new QWidget(this);
QPushButton *button = new QPushButton(QStringLiteral("Open"));
label = new QLabel(QStringLiteral("Output appears here"));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button);
layout->addWidget(label);
central->setLayout(layout);
setCentralWidget(central);
connect(button, SIGNAL(clicked()), this, SLOT(createWindow()));
}
private slots:
void createWindow() {
SecondWindow *window = new SecondWindow(this);
connect(window, SIGNAL(textChanged(QString)), this, SLOT(setLabelText(QString)));
window->resize(300, 300);
window->exec();
}
void setLabelText(const QString &text) {
label->setText(text);
}
private:
QLabel *label;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FirstWindow w;
w.resize(400, 400);
w.show();
return a.exec();
}
#include "main.moc"
Not that the SecondWindow listens for changes on the QLineEdit and emits its own signal when that value changes. Then the FirstWindow just connects to that signal and changes its own QLabel whenever it receives the signal.