mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-05 08:45:25 +08:00
qt 6.5.1 original
This commit is contained in:
16
tests/manual/qscreen/CMakeLists.txt
Normal file
16
tests/manual/qscreen/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## qscreen Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_manual_test(qscreen
|
||||
SOURCES
|
||||
main.cpp
|
||||
propertyfield.cpp propertyfield.h
|
||||
propertywatcher.cpp propertywatcher.h
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
36
tests/manual/qscreen/README
Normal file
36
tests/manual/qscreen/README
Normal file
@ -0,0 +1,36 @@
|
||||
To test whether QScreen properties are updated properly when the screen
|
||||
actually changes, you will need to run some kind of control panel to make
|
||||
changes, and this test program at the same time. E.g. on Linux, you can use
|
||||
xrandr with various parameters on the command line, but there is also a nice
|
||||
GUI called arandr which will probably work on any distro. Real-world users
|
||||
would probably use the Gnome or KDE control panels, so that's also a good way
|
||||
to test. On OSX you can make changes in System Preferences | Displays, and you
|
||||
can also configure it to put a "monitors" icon on the menubar with a drop-down
|
||||
menu for convenience. On Windows you can right-click on the desktop to get
|
||||
display settings.
|
||||
|
||||
Note that on Linux, if you have one graphics card with two outputs, typically
|
||||
the two monitors connected to the outputs are combined into a single virtual
|
||||
"screen", but each screen has multiple outputs. In that case there will be a
|
||||
unique QScreen for each output, and they will be virtual siblings. The virtual
|
||||
geometry depends on how you arrange the monitors (second one is to the right,
|
||||
or above the first one, for example). This test app will
|
||||
create two windows, and will center one each screen, by setting the geometry.
|
||||
|
||||
Alternatively you can configure xorg.conf to create separate screens for each
|
||||
graphics card; then the mouse cursor can move between the screens, but
|
||||
application windows cannot: each app needs to be started on the screen that
|
||||
you want to run it on (by specifying e.g. DISPLAY=:0.1 for the second screen),
|
||||
or the application has to set the desired screen via QWindow::setScreen() before
|
||||
showing the window.
|
||||
|
||||
The physical size of the screen is considered to be a constant. This can create
|
||||
discrepancies in DPI when orientation is changed, or when the screen is
|
||||
actually a VNC server and you change the resolution. So maybe
|
||||
QScreen::physicalSize should also have a notifier, but that doesn't physically
|
||||
make sense except when the screen is virtual.
|
||||
|
||||
Another case is running two separate X servers on two graphics cards. In that
|
||||
case they really do not know about each other, even at the xlib/xcb level, so
|
||||
this test is irrelevant. You can run the test independently on each X server,
|
||||
but you will just get one QScreen instance on each.
|
240
tests/manual/qscreen/main.cpp
Normal file
240
tests/manual/qscreen/main.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "propertywatcher.h"
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
#include <QDebug>
|
||||
#include <QTextStream>
|
||||
#include <QFormLayout>
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QAction>
|
||||
#include <QStatusBar>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
|
||||
|
||||
class MouseMonitor : public QLabel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MouseMonitor() : m_grabbed(false) {
|
||||
setMinimumSize(540, 240);
|
||||
setAlignment(Qt::AlignCenter);
|
||||
setMouseTracking(true);
|
||||
setWindowTitle(QLatin1String("Mouse Monitor"));
|
||||
updateText();
|
||||
}
|
||||
|
||||
void updateText() {
|
||||
QString txt = m_grabbed ?
|
||||
QLatin1String("Left-click to test QGuiApplication::topLevelAt(click pos)\nRight-click to ungrab\n") :
|
||||
QLatin1String("Left-click to grab mouse\n");
|
||||
if (!m_cursorPos.isNull()) {
|
||||
const auto screen = QGuiApplication::screenAt(m_cursorPos);
|
||||
const auto screenNum = screen ? QGuiApplication::screens().indexOf(screen) : 0;
|
||||
txt += QString(QLatin1String("Current mouse position: %1, %2 on screen %3\n"))
|
||||
.arg(m_cursorPos.x()).arg(m_cursorPos.y()).arg(screenNum);
|
||||
if (QGuiApplication::mouseButtons() & Qt::LeftButton) {
|
||||
QWindow *win = QGuiApplication::topLevelAt(m_cursorPos);
|
||||
txt += QString(QLatin1String("Top-level window found? %1\n"))
|
||||
.arg(win ? (win->title().isEmpty() ? "no title" : win->title()) : "none");
|
||||
}
|
||||
}
|
||||
setText(txt);
|
||||
}
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *ev) override {
|
||||
m_cursorPos = ev->screenPos().toPoint();
|
||||
updateText();
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent *ev) override {
|
||||
m_cursorPos = ev->screenPos().toPoint();
|
||||
qDebug() << "top level @" << m_cursorPos << ":" << QGuiApplication::topLevelAt(m_cursorPos);
|
||||
updateText();
|
||||
if (!m_grabbed) {
|
||||
grabMouse(Qt::CrossCursor);
|
||||
m_grabbed = true;
|
||||
} else if (ev->button() == Qt::RightButton) {
|
||||
setVisible(false);
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QPoint m_cursorPos;
|
||||
bool m_grabbed;
|
||||
};
|
||||
|
||||
class ScreenPropertyWatcher : public PropertyWatcher
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScreenPropertyWatcher(QWidget *wp = nullptr) : PropertyWatcher(nullptr, QString(), wp)
|
||||
{
|
||||
// workaround for the fact that virtualSiblings is not a property,
|
||||
// thus there is no change notification:
|
||||
// allow the user to update the field manually
|
||||
connect(this, &PropertyWatcher::updatedAllFields, this, &ScreenPropertyWatcher::updateSiblings);
|
||||
}
|
||||
|
||||
QScreen *screenSubject() const { return qobject_cast<QScreen *>(subject()); }
|
||||
void setScreenSubject(QScreen *s, const QString &annotation = QString())
|
||||
{
|
||||
setSubject(s, annotation);
|
||||
updateSiblings();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void updateSiblings();
|
||||
};
|
||||
|
||||
void ScreenPropertyWatcher::updateSiblings()
|
||||
{
|
||||
const QScreen *screen = screenSubject();
|
||||
if (!screen)
|
||||
return;
|
||||
const QString objectName = QLatin1String("siblings");
|
||||
QLineEdit *siblingsField = findChild<QLineEdit *>(objectName);
|
||||
if (!siblingsField) {
|
||||
siblingsField = new QLineEdit(this);
|
||||
siblingsField->setObjectName(objectName);
|
||||
siblingsField->setReadOnly(true);
|
||||
formLayout()->insertRow(0, QLatin1String("virtualSiblings"), siblingsField);
|
||||
}
|
||||
QString text;
|
||||
foreach (const QScreen *sibling, screen->virtualSiblings()) {
|
||||
if (!text.isEmpty())
|
||||
text += QLatin1String(", ");
|
||||
text += sibling->name();
|
||||
}
|
||||
siblingsField->setText(text);
|
||||
}
|
||||
|
||||
class ScreenWatcherMainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScreenWatcherMainWindow(QScreen *screen);
|
||||
|
||||
QScreen *screenSubject() const { return m_watcher->screenSubject(); }
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
void startMouseMonitor();
|
||||
|
||||
private:
|
||||
const QString m_annotation;
|
||||
ScreenPropertyWatcher *m_watcher;
|
||||
};
|
||||
|
||||
static int i = 0;
|
||||
|
||||
ScreenWatcherMainWindow::ScreenWatcherMainWindow(QScreen *screen)
|
||||
: m_annotation(QLatin1Char('#') + QString::number(i++))
|
||||
, m_watcher(new ScreenPropertyWatcher(this))
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setCentralWidget(m_watcher);
|
||||
m_watcher->setScreenSubject(screen, m_annotation);
|
||||
|
||||
QMenu *fileMenu = menuBar()->addMenu(QLatin1String("&File"));
|
||||
QAction *a = fileMenu->addAction(QLatin1String("Close"));
|
||||
a->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_W));
|
||||
connect(a, SIGNAL(triggered()), this, SLOT(close()));
|
||||
a = fileMenu->addAction(QLatin1String("Quit"));
|
||||
a->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
|
||||
connect(a, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
|
||||
QMenu *toolsMenu = menuBar()->addMenu(QLatin1String("&Tools"));
|
||||
a = toolsMenu->addAction(QLatin1String("Mouse Monitor"));
|
||||
a->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_M));
|
||||
connect(a, &QAction::triggered, this, &ScreenWatcherMainWindow::startMouseMonitor);
|
||||
}
|
||||
|
||||
static inline QString msgScreenChange(const QWidget *w, const QScreen *oldScreen, const QScreen *newScreen)
|
||||
{
|
||||
QString result;
|
||||
const QRect geometry = w->geometry();
|
||||
const QPoint pos = QCursor::pos();
|
||||
if (!newScreen) {
|
||||
result = QLatin1String("Screen changed --> null");
|
||||
} else if (!oldScreen) {
|
||||
QTextStream(&result) << "Screen changed null --> \"" << newScreen->name() << "\" at "
|
||||
<< pos.x() << ',' << pos.y() << " geometry: " << geometry.width()
|
||||
<< 'x' << geometry.height() << Qt::forcesign << geometry.x()
|
||||
<< geometry.y() << '.';
|
||||
} else {
|
||||
QTextStream(&result) << "Screen changed \"" << oldScreen->name() << "\" --> \""
|
||||
<< newScreen->name() << "\" at " << pos.x() << ',' << pos.y()
|
||||
<< " geometry: " << geometry.width() << 'x' << geometry.height()
|
||||
<< Qt::forcesign << geometry.x() << geometry.y() << '.';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ScreenWatcherMainWindow::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ScreenChangeInternal) {
|
||||
QScreen *newScreen = windowHandle()->screen();
|
||||
const QString message = msgScreenChange(this, m_watcher->screenSubject(), newScreen);
|
||||
qDebug().noquote() << message;
|
||||
statusBar()->showMessage(message);
|
||||
m_watcher->setScreenSubject(newScreen, m_annotation);
|
||||
}
|
||||
return QMainWindow::event(event);
|
||||
}
|
||||
|
||||
void ScreenWatcherMainWindow::startMouseMonitor()
|
||||
{
|
||||
MouseMonitor *mm = new MouseMonitor();
|
||||
mm->show();
|
||||
}
|
||||
|
||||
void screenAdded(QScreen* screen)
|
||||
{
|
||||
qDebug("\nscreenAdded %s siblings %d fast %s", qPrintable(screen->name()), screen->virtualSiblings().count(),
|
||||
(screen->virtualSiblings().isEmpty() ? "none" : qPrintable(screen->virtualSiblings().first()->name())));
|
||||
ScreenWatcherMainWindow *w = new ScreenWatcherMainWindow(screen);
|
||||
|
||||
w->setScreen(screen);
|
||||
w->show();
|
||||
|
||||
// Position the windows so that they end up at the center of the corresponding screen.
|
||||
QRect geom = w->geometry();
|
||||
geom.setSize(w->sizeHint());
|
||||
if (geom.height() > screen->geometry().height())
|
||||
geom.setHeight(screen->geometry().height() * 9 / 10);
|
||||
geom.moveCenter(screen->geometry().center());
|
||||
w->setGeometry(geom);
|
||||
}
|
||||
|
||||
void screenRemoved(QScreen* screen)
|
||||
{
|
||||
const QWidgetList topLevels = QApplication::topLevelWidgets();
|
||||
for (int i = topLevels.size() - 1; i >= 0; --i) {
|
||||
if (ScreenWatcherMainWindow *sw = qobject_cast<ScreenWatcherMainWindow *>(topLevels.at(i))) {
|
||||
if (sw->screenSubject() == screen)
|
||||
sw->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
QList<QScreen *> screens = QGuiApplication::screens();
|
||||
foreach (QScreen *screen, screens)
|
||||
screenAdded(screen);
|
||||
QObject::connect((const QGuiApplication*)QGuiApplication::instance(), &QGuiApplication::screenAdded, &screenAdded);
|
||||
QObject::connect((const QGuiApplication*)QGuiApplication::instance(), &QGuiApplication::screenRemoved, &screenRemoved);
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
79
tests/manual/qscreen/propertyfield.cpp
Normal file
79
tests/manual/qscreen/propertyfield.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "propertyfield.h"
|
||||
#include <QDebug>
|
||||
|
||||
PropertyField::PropertyField(QObject* subject, const QMetaProperty& prop, QWidget *parent)
|
||||
: QLineEdit(parent), m_subject(subject), m_lastChangeTime(), m_prop(prop)
|
||||
, m_defaultBrush(palette().brush(QPalette::Active, QPalette::Text))
|
||||
{
|
||||
setReadOnly(true);
|
||||
if (prop.hasNotifySignal()) {
|
||||
QMetaMethod signal = prop.notifySignal();
|
||||
QMetaMethod updateSlot = metaObject()->method(metaObject()->indexOfSlot("propertyChanged()"));
|
||||
connect(m_subject, signal, this, updateSlot);
|
||||
}
|
||||
propertyChanged();
|
||||
}
|
||||
|
||||
QString PropertyField::valueToString(QVariant val)
|
||||
{
|
||||
if (m_prop.isEnumType())
|
||||
return QString::fromUtf8(m_prop.enumerator().valueToKey(val.toInt()));
|
||||
|
||||
QString text;
|
||||
switch (val.type()) {
|
||||
case QVariant::Double:
|
||||
text = QString("%1").arg(val.toReal(), 0, 'f', 4);
|
||||
break;
|
||||
case QVariant::Size:
|
||||
text = QString("%1 x %2").arg(val.toSize().width()).arg(val.toSize().height());
|
||||
break;
|
||||
case QVariant::SizeF:
|
||||
text = QString("%1 x %2").arg(val.toSizeF().width()).arg(val.toSizeF().height());
|
||||
break;
|
||||
case QVariant::Rect: {
|
||||
QRect rect = val.toRect();
|
||||
text = QString("%1 x %2 %3%4 %5%6").arg(rect.width())
|
||||
.arg(rect.height()).arg(rect.x() < 0 ? "" : "+").arg(rect.x())
|
||||
.arg(rect.y() < 0 ? "" : "+").arg(rect.y());
|
||||
} break;
|
||||
default:
|
||||
text = val.toString();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
void PropertyField::propertyChanged()
|
||||
{
|
||||
if (m_prop.isReadable()) {
|
||||
QVariant val = m_prop.read(m_subject);
|
||||
QString text = valueToString(val);
|
||||
QPalette modPalette = palette();
|
||||
|
||||
// If we are seeing a value for the first time,
|
||||
// pretend it was that way for a while already.
|
||||
if (m_lastText.isEmpty()) {
|
||||
m_lastText = text;
|
||||
m_lastTextShowing = text;
|
||||
}
|
||||
|
||||
qDebug() << " " << QString::fromUtf8(m_prop.name()) << ':' << val;
|
||||
// If the value has recently changed, show the change
|
||||
if (text != m_lastText || m_lastChangeTime.elapsed() < 1000) {
|
||||
setText(m_lastTextShowing + " -> " + text);
|
||||
modPalette.setBrush(QPalette::Text, Qt::red);
|
||||
m_lastChangeTime.start();
|
||||
m_lastText = text;
|
||||
}
|
||||
// If the value hasn't changed recently, just show the current value
|
||||
else {
|
||||
setText(text);
|
||||
m_lastText = text;
|
||||
m_lastTextShowing = text;
|
||||
modPalette.setBrush(QPalette::Text, m_defaultBrush);
|
||||
}
|
||||
setPalette(modPalette);
|
||||
}
|
||||
}
|
39
tests/manual/qscreen/propertyfield.h
Normal file
39
tests/manual/qscreen/propertyfield.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef PROPERTYFIELD_H
|
||||
#define PROPERTYFIELD_H
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QMetaProperty>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
/*!
|
||||
A QLineEdit for viewing the text form of a property on an object.
|
||||
Automatically stays up-to-date when the property changes.
|
||||
(This is rather like a QML TextField bound to a property.)
|
||||
*/
|
||||
class PropertyField : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PropertyField(QObject* subject, const QMetaProperty& prop, QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void propertyChanged();
|
||||
|
||||
protected:
|
||||
QString valueToString(QVariant val);
|
||||
|
||||
private:
|
||||
QObject* m_subject;
|
||||
QString m_lastText;
|
||||
QString m_lastTextShowing;
|
||||
QElapsedTimer m_lastChangeTime;
|
||||
const QMetaProperty m_prop;
|
||||
QBrush m_defaultBrush;
|
||||
};
|
||||
|
||||
#endif // PROPERTYFIELD_H
|
97
tests/manual/qscreen/propertywatcher.cpp
Normal file
97
tests/manual/qscreen/propertywatcher.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "propertywatcher.h"
|
||||
#include <QMetaProperty>
|
||||
#include <QFormLayout>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include "propertyfield.h"
|
||||
|
||||
PropertyWatcher::PropertyWatcher(QObject *subject, QString annotation, QWidget *parent)
|
||||
: QWidget(parent), m_subject(nullptr), m_formLayout(new QFormLayout(this))
|
||||
{
|
||||
setMinimumSize(450, 300);
|
||||
m_formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
||||
setSubject(subject, annotation);
|
||||
}
|
||||
|
||||
class UpdatesEnabledBlocker
|
||||
{
|
||||
Q_DISABLE_COPY(UpdatesEnabledBlocker);
|
||||
public:
|
||||
explicit UpdatesEnabledBlocker(QWidget *w) : m_widget(w)
|
||||
{
|
||||
m_widget->setUpdatesEnabled(false);
|
||||
}
|
||||
~UpdatesEnabledBlocker()
|
||||
{
|
||||
m_widget->setUpdatesEnabled(true);
|
||||
m_widget->update();
|
||||
}
|
||||
|
||||
private:
|
||||
QWidget *m_widget;
|
||||
};
|
||||
|
||||
void PropertyWatcher::setSubject(QObject *s, const QString &annotation)
|
||||
{
|
||||
if (s == m_subject)
|
||||
return;
|
||||
|
||||
UpdatesEnabledBlocker blocker(this);
|
||||
|
||||
if (m_subject) {
|
||||
disconnect(m_subject, &QObject::destroyed, this, &PropertyWatcher::subjectDestroyed);
|
||||
for (int i = m_formLayout->count() - 1; i >= 0; --i) {
|
||||
QLayoutItem *item = m_formLayout->takeAt(i);
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
window()->setWindowTitle(QString());
|
||||
window()->setWindowIconText(QString());
|
||||
}
|
||||
|
||||
m_subject = s;
|
||||
if (!m_subject)
|
||||
return;
|
||||
|
||||
const QMetaObject* meta = m_subject->metaObject();
|
||||
QString title = QLatin1String("Properties ") + QLatin1String(meta->className());
|
||||
if (!m_subject->objectName().isEmpty())
|
||||
title += QLatin1Char(' ') + m_subject->objectName();
|
||||
if (!annotation.isEmpty())
|
||||
title += QLatin1Char(' ') + annotation;
|
||||
window()->setWindowTitle(title);
|
||||
|
||||
for (int i = 0, count = meta->propertyCount(); i < count; ++i) {
|
||||
const QMetaProperty prop = meta->property(i);
|
||||
if (prop.isReadable()) {
|
||||
QLabel *label = new QLabel(prop.name(), this);
|
||||
PropertyField *field = new PropertyField(m_subject, prop, this);
|
||||
m_formLayout->addRow(label, field);
|
||||
if (!qstrcmp(prop.name(), "name"))
|
||||
window()->setWindowIconText(prop.read(m_subject).toString());
|
||||
label->setVisible(true);
|
||||
field->setVisible(true);
|
||||
}
|
||||
}
|
||||
connect(m_subject, &QObject::destroyed, this, &PropertyWatcher::subjectDestroyed);
|
||||
|
||||
QPushButton *updateButton = new QPushButton(QLatin1String("Update"), this);
|
||||
connect(updateButton, &QPushButton::clicked, this, &PropertyWatcher::updateAllFields);
|
||||
m_formLayout->addRow(QString(), updateButton);
|
||||
}
|
||||
|
||||
void PropertyWatcher::updateAllFields()
|
||||
{
|
||||
QList<PropertyField *> fields = findChildren<PropertyField*>();
|
||||
foreach (PropertyField *field, fields)
|
||||
field->propertyChanged();
|
||||
emit updatedAllFields(this);
|
||||
}
|
||||
|
||||
void PropertyWatcher::subjectDestroyed()
|
||||
{
|
||||
qDebug("screen destroyed");
|
||||
}
|
36
tests/manual/qscreen/propertywatcher.h
Normal file
36
tests/manual/qscreen/propertywatcher.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef PROPERTY_WATCHER_H
|
||||
#define PROPERTY_WATCHER_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLineEdit;
|
||||
class QFormLayout;
|
||||
|
||||
class PropertyWatcher : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PropertyWatcher(QObject* subject = nullptr, QString annotation = QString(), QWidget *parent = nullptr);
|
||||
|
||||
QFormLayout *formLayout() { return m_formLayout; }
|
||||
|
||||
QObject *subject() const { return m_subject; }
|
||||
void setSubject(QObject *s, const QString &annotation = QString());
|
||||
|
||||
public slots:
|
||||
void updateAllFields();
|
||||
void subjectDestroyed();
|
||||
|
||||
signals:
|
||||
void updatedAllFields(PropertyWatcher* sender);
|
||||
|
||||
private:
|
||||
QObject* m_subject;
|
||||
QFormLayout * m_formLayout;
|
||||
};
|
||||
|
||||
#endif // PROPERTY_WATCHER_H
|
13
tests/manual/qscreen/qscreen.pro
Normal file
13
tests/manual/qscreen/qscreen.pro
Normal file
@ -0,0 +1,13 @@
|
||||
QT += core gui widgets
|
||||
CONFIG += console
|
||||
|
||||
TARGET = qscreen
|
||||
TEMPLATE = app
|
||||
|
||||
SOURCES += main.cpp \
|
||||
propertywatcher.cpp \
|
||||
propertyfield.cpp
|
||||
|
||||
HEADERS += \
|
||||
propertywatcher.h \
|
||||
propertyfield.h
|
Reference in New Issue
Block a user