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 "qspinbox.h"
|
||||
#include "qdialogbuttonbox.h"
|
||||
#include "qscreen.h"
|
||||
#include "qcursor.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -1417,6 +1419,15 @@ bool QColorDialogPrivate::selectColor(const QColor &col)
|
||||
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
|
||||
void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
|
||||
{
|
||||
@ -1442,6 +1453,48 @@ void QColorDialogPrivate::_q_newStandard(int r, int c)
|
||||
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)
|
||||
{
|
||||
Q_Q(QColorDialog);
|
||||
@ -1450,7 +1503,7 @@ void QColorDialogPrivate::init(const QColor &initial)
|
||||
q->setWindowTitle(QColorDialog::tr("Select Color"));
|
||||
|
||||
nativeDialogInUse = (platformColorDialogHelper() != 0);
|
||||
|
||||
screenColorPicking = false;
|
||||
nextCust = 0;
|
||||
QVBoxLayout *mainLay = new QVBoxLayout(q);
|
||||
// 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(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)
|
||||
leftLay->addStretch();
|
||||
#endif
|
||||
@ -1658,6 +1720,11 @@ static const Qt::WindowFlags DefaultWindowFlags =
|
||||
during the execution of the program. Use setCustomColor() to set
|
||||
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
|
||||
how to use QColorDialog as well as other built-in Qt dialogs.
|
||||
|
||||
@ -1971,6 +2038,57 @@ void QColorDialog::changeEvent(QEvent *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
|
||||
is shown with exec(), done() causes the local event loop to finish,
|
||||
|
@ -112,6 +112,9 @@ Q_SIGNALS:
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *event);
|
||||
virtual void mouseMoveEvent(QMouseEvent *);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *);
|
||||
virtual void keyPressEvent(QKeyEvent *);
|
||||
void done(int result);
|
||||
|
||||
private:
|
||||
@ -122,6 +125,7 @@ private:
|
||||
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_newStandard(int, int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_pickScreenColor())
|
||||
friend class QColorShower;
|
||||
};
|
||||
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
void setCurrentColor(QRgb rgb);
|
||||
void setCurrentQColor(const QColor &color);
|
||||
bool selectColor(const QColor &color);
|
||||
QColor grabScreenColor(const QPoint &p);
|
||||
|
||||
int currentAlpha() const;
|
||||
void setCurrentAlpha(int a);
|
||||
@ -100,6 +101,8 @@ public:
|
||||
void _q_newColorTypedIn(QRgb rgb);
|
||||
void _q_newCustom(int, int);
|
||||
void _q_newStandard(int, int);
|
||||
void _q_pickScreenColor();
|
||||
void releaseColorPicking();
|
||||
|
||||
QWellArray *custom;
|
||||
QWellArray *standard;
|
||||
@ -111,12 +114,16 @@ public:
|
||||
QColorShower *cs;
|
||||
QLabel *lblBasicColors;
|
||||
QLabel *lblCustomColors;
|
||||
QLabel *lblScreenColorInfo;
|
||||
QPushButton *ok;
|
||||
QPushButton *cancel;
|
||||
QPushButton *addCusBt;
|
||||
QPushButton *screenColorPickerButton;
|
||||
QColor selectedQColor;
|
||||
int nextCust;
|
||||
bool smallDisplay;
|
||||
bool screenColorPicking;
|
||||
QRgb beforeScreenColorPicking;
|
||||
QSharedPointer<QColorDialogOptions> options;
|
||||
|
||||
QPointer<QObject> receiverToDisconnectOnClose;
|
||||
|
Loading…
x
Reference in New Issue
Block a user