Add a screen color picker button to QColorDialog
Add a new button with which any color present on the screen can be picked up. This feature is very useful in any image processing application. Notice: --I have setMouseTracking to true because I consider that it makes much easier to grab the desired color. --I have set the cursor manually because for some unknown reason the cursor wouldn't change with grabMouse(Qt::CrossCursor). Task-number: QTBUG-14332 Change-Id: I39e3543d3ed55276f43d569a2f03087bbf89b27a Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
67d7651212
commit
d928dbbc91
@ -63,6 +63,8 @@
|
|||||||
#include "qmimedata.h"
|
#include "qmimedata.h"
|
||||||
#include "qspinbox.h"
|
#include "qspinbox.h"
|
||||||
#include "qdialogbuttonbox.h"
|
#include "qdialogbuttonbox.h"
|
||||||
|
#include "qscreen.h"
|
||||||
|
#include "qcursor.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -1417,6 +1419,15 @@ bool QColorDialogPrivate::selectColor(const QColor &col)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QColor QColorDialogPrivate::grabScreenColor(const QPoint &p)
|
||||||
|
{
|
||||||
|
const QDesktopWidget *desktop = QApplication::desktop();
|
||||||
|
const QPixmap pixmap = QGuiApplication::screens().at(desktop->screenNumber())->grabWindow(desktop->winId(),
|
||||||
|
p.x(), p.y(), 1, 1);
|
||||||
|
QImage i = pixmap.toImage();
|
||||||
|
return i.pixel(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
//sets all widgets except cs to display rgb
|
//sets all widgets except cs to display rgb
|
||||||
void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
|
void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
|
||||||
{
|
{
|
||||||
@ -1442,6 +1453,48 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
|
|||||||
custom->setSelected(-1,-1);
|
custom->setSelected(-1,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QColorDialogPrivate::_q_pickScreenColor()
|
||||||
|
{
|
||||||
|
Q_Q(QColorDialog);
|
||||||
|
screenColorPicking = true;
|
||||||
|
// If user pushes Escape, the last color before picking will be restored.
|
||||||
|
beforeScreenColorPicking = cs->currentColor();
|
||||||
|
/*For some reason, q->grabMouse(Qt::CrossCursor) doesn't change
|
||||||
|
* the cursor, and therefore I have to change it manually.
|
||||||
|
*/
|
||||||
|
q->grabMouse();
|
||||||
|
q->setCursor(Qt::CrossCursor);
|
||||||
|
q->grabKeyboard();
|
||||||
|
/* With setMouseTracking(true) the desired color can be more precisedly picked up,
|
||||||
|
* and continuously pushing the mouse button is not necessary.
|
||||||
|
*/
|
||||||
|
q->setMouseTracking(true);
|
||||||
|
|
||||||
|
addCusBt->setDisabled(true);
|
||||||
|
buttons->setDisabled(true);
|
||||||
|
screenColorPickerButton->setDisabled(true);
|
||||||
|
|
||||||
|
q->setCurrentColor(grabScreenColor(QCursor::pos()));
|
||||||
|
lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
|
||||||
|
.arg(QCursor::pos().x())
|
||||||
|
.arg(QCursor::pos().y())
|
||||||
|
.arg(q->currentColor().name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QColorDialogPrivate::releaseColorPicking()
|
||||||
|
{
|
||||||
|
Q_Q(QColorDialog);
|
||||||
|
screenColorPicking = false;
|
||||||
|
q->releaseMouse();
|
||||||
|
q->releaseKeyboard();
|
||||||
|
q->setCursor(Qt::ArrowCursor);
|
||||||
|
q->setMouseTracking(false);
|
||||||
|
lblScreenColorInfo->setText(QLatin1String("\n"));
|
||||||
|
addCusBt->setDisabled(false);
|
||||||
|
buttons->setDisabled(false);
|
||||||
|
screenColorPickerButton->setDisabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
void QColorDialogPrivate::init(const QColor &initial)
|
void QColorDialogPrivate::init(const QColor &initial)
|
||||||
{
|
{
|
||||||
Q_Q(QColorDialog);
|
Q_Q(QColorDialog);
|
||||||
@ -1450,7 +1503,7 @@ void QColorDialogPrivate::init(const QColor &initial)
|
|||||||
q->setWindowTitle(QColorDialog::tr("Select Color"));
|
q->setWindowTitle(QColorDialog::tr("Select Color"));
|
||||||
|
|
||||||
nativeDialogInUse = (platformColorDialogHelper() != 0);
|
nativeDialogInUse = (platformColorDialogHelper() != 0);
|
||||||
|
screenColorPicking = false;
|
||||||
nextCust = 0;
|
nextCust = 0;
|
||||||
QVBoxLayout *mainLay = new QVBoxLayout(q);
|
QVBoxLayout *mainLay = new QVBoxLayout(q);
|
||||||
// there's nothing in this dialog that benefits from sizing up
|
// there's nothing in this dialog that benefits from sizing up
|
||||||
@ -1486,6 +1539,15 @@ void QColorDialogPrivate::init(const QColor &initial)
|
|||||||
leftLay->addWidget(lblBasicColors);
|
leftLay->addWidget(lblBasicColors);
|
||||||
leftLay->addWidget(standard);
|
leftLay->addWidget(standard);
|
||||||
|
|
||||||
|
#if !defined(Q_OS_WINCE) && !defined(QT_SMALL_COLORDIALOG)
|
||||||
|
// The screen color picker button
|
||||||
|
screenColorPickerButton = new QPushButton(QColorDialog::tr("Pick Screen Color"));
|
||||||
|
leftLay->addWidget(screenColorPickerButton);
|
||||||
|
lblScreenColorInfo = new QLabel(QLatin1String("\n"));
|
||||||
|
leftLay->addWidget(lblScreenColorInfo);
|
||||||
|
q->connect(screenColorPickerButton, SIGNAL(clicked()), SLOT(_q_pickScreenColor()));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(Q_OS_WINCE)
|
#if !defined(Q_OS_WINCE)
|
||||||
leftLay->addStretch();
|
leftLay->addStretch();
|
||||||
#endif
|
#endif
|
||||||
@ -1658,6 +1720,11 @@ static const Qt::WindowFlags DefaultWindowFlags =
|
|||||||
during the execution of the program. Use setCustomColor() to set
|
during the execution of the program. Use setCustomColor() to set
|
||||||
the custom colors, and use customColor() to get them.
|
the custom colors, and use customColor() to get them.
|
||||||
|
|
||||||
|
When pressing the "Pick Screen Color" button, the cursor changes to a haircross
|
||||||
|
and the colors on the screen are scanned. The user can pick up one by clicking
|
||||||
|
the mouse or the Enter button. Pressing Escape restores the last color selected
|
||||||
|
before entering this mode.
|
||||||
|
|
||||||
The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
|
The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
|
||||||
how to use QColorDialog as well as other built-in Qt dialogs.
|
how to use QColorDialog as well as other built-in Qt dialogs.
|
||||||
|
|
||||||
@ -1971,6 +2038,57 @@ void QColorDialog::changeEvent(QEvent *e)
|
|||||||
QDialog::changeEvent(e);
|
QDialog::changeEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
void QColorDialog::mouseMoveEvent(QMouseEvent *e)
|
||||||
|
{
|
||||||
|
Q_D(QColorDialog);
|
||||||
|
if (d->screenColorPicking) {
|
||||||
|
setCurrentColor(d->grabScreenColor(e->globalPos()));
|
||||||
|
d->lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
|
||||||
|
.arg(e->globalPos().x())
|
||||||
|
.arg(e->globalPos().y())
|
||||||
|
.arg(currentColor().name()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QDialog::mouseMoveEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
void QColorDialog::mouseReleaseEvent(QMouseEvent *e)
|
||||||
|
{
|
||||||
|
Q_D(QColorDialog);
|
||||||
|
if (d->screenColorPicking) {
|
||||||
|
setCurrentColor(d->grabScreenColor(e->globalPos()));
|
||||||
|
d->releaseColorPicking();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QDialog::mouseReleaseEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
void QColorDialog::keyPressEvent(QKeyEvent *e)
|
||||||
|
{
|
||||||
|
Q_D(QColorDialog);
|
||||||
|
if (d->screenColorPicking) {
|
||||||
|
if (e->key() == Qt::Key_Escape) {
|
||||||
|
d->releaseColorPicking();
|
||||||
|
d->setCurrentColor(d->beforeScreenColorPicking);
|
||||||
|
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
|
||||||
|
setCurrentColor(d->grabScreenColor(QCursor::pos()));
|
||||||
|
d->releaseColorPicking();
|
||||||
|
}
|
||||||
|
e->accept();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QDialog::keyPressEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Closes the dialog and sets its result code to \a result. If this dialog
|
Closes the dialog and sets its result code to \a result. If this dialog
|
||||||
is shown with exec(), done() causes the local event loop to finish,
|
is shown with exec(), done() causes the local event loop to finish,
|
||||||
|
@ -112,6 +112,9 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void changeEvent(QEvent *event);
|
void changeEvent(QEvent *event);
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *);
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent *);
|
||||||
|
virtual void keyPressEvent(QKeyEvent *);
|
||||||
void done(int result);
|
void done(int result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -122,6 +125,7 @@ private:
|
|||||||
Q_PRIVATE_SLOT(d_func(), void _q_newColorTypedIn(QRgb rgb))
|
Q_PRIVATE_SLOT(d_func(), void _q_newColorTypedIn(QRgb rgb))
|
||||||
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
|
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
|
||||||
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
|
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void _q_pickScreenColor())
|
||||||
friend class QColorShower;
|
friend class QColorShower;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
void setCurrentColor(QRgb rgb);
|
void setCurrentColor(QRgb rgb);
|
||||||
void setCurrentQColor(const QColor &color);
|
void setCurrentQColor(const QColor &color);
|
||||||
bool selectColor(const QColor &color);
|
bool selectColor(const QColor &color);
|
||||||
|
QColor grabScreenColor(const QPoint &p);
|
||||||
|
|
||||||
int currentAlpha() const;
|
int currentAlpha() const;
|
||||||
void setCurrentAlpha(int a);
|
void setCurrentAlpha(int a);
|
||||||
@ -100,6 +101,8 @@ public:
|
|||||||
void _q_newColorTypedIn(QRgb rgb);
|
void _q_newColorTypedIn(QRgb rgb);
|
||||||
void _q_newCustom(int, int);
|
void _q_newCustom(int, int);
|
||||||
void _q_newStandard(int, int);
|
void _q_newStandard(int, int);
|
||||||
|
void _q_pickScreenColor();
|
||||||
|
void releaseColorPicking();
|
||||||
|
|
||||||
QWellArray *custom;
|
QWellArray *custom;
|
||||||
QWellArray *standard;
|
QWellArray *standard;
|
||||||
@ -111,12 +114,16 @@ public:
|
|||||||
QColorShower *cs;
|
QColorShower *cs;
|
||||||
QLabel *lblBasicColors;
|
QLabel *lblBasicColors;
|
||||||
QLabel *lblCustomColors;
|
QLabel *lblCustomColors;
|
||||||
|
QLabel *lblScreenColorInfo;
|
||||||
QPushButton *ok;
|
QPushButton *ok;
|
||||||
QPushButton *cancel;
|
QPushButton *cancel;
|
||||||
QPushButton *addCusBt;
|
QPushButton *addCusBt;
|
||||||
|
QPushButton *screenColorPickerButton;
|
||||||
QColor selectedQColor;
|
QColor selectedQColor;
|
||||||
int nextCust;
|
int nextCust;
|
||||||
bool smallDisplay;
|
bool smallDisplay;
|
||||||
|
bool screenColorPicking;
|
||||||
|
QRgb beforeScreenColorPicking;
|
||||||
QSharedPointer<QColorDialogOptions> options;
|
QSharedPointer<QColorDialogOptions> options;
|
||||||
|
|
||||||
QPointer<QObject> receiverToDisconnectOnClose;
|
QPointer<QObject> receiverToDisconnectOnClose;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user