diff options
Diffstat (limited to 'src/widgets')
29 files changed, 285 insertions, 483 deletions
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index ce30f50616b..c0be3debe49 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -681,6 +681,7 @@ qt_internal_extend_target(Widgets CONDITION MACOS AND (QT_FEATURE_menu OR QT_FEA qt_internal_extend_target(Widgets CONDITION QT_FEATURE_colordialog SOURCES dialogs/qcolordialog.cpp dialogs/qcolordialog.h + dialogs/qcolorwell_p.h ) qt_internal_extend_target(Widgets CONDITION QT_FEATURE_dialog diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index 608a99b575d..cd28a61f427 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -958,54 +958,22 @@ QPoint QAccessibleTextWidget::scrollBarPosition() const QString QAccessibleTextWidget::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const { - Q_ASSERT(startOffset); - Q_ASSERT(endOffset); - - QTextCursor cursor = textCursor(); - cursor.setPosition(offset); - std::pair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - cursor.setPosition(boundaries.first - 1); - boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - - *startOffset = boundaries.first; - *endOffset = boundaries.second; - - return text(boundaries.first, boundaries.second); - } - + return qt_accTextBeforeOffsetHelper(*this, textCursor(), offset, boundaryType, startOffset, + endOffset); +} QString QAccessibleTextWidget::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const { - Q_ASSERT(startOffset); - Q_ASSERT(endOffset); - - QTextCursor cursor = textCursor(); - cursor.setPosition(offset); - std::pair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - cursor.setPosition(boundaries.second); - boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - - *startOffset = boundaries.first; - *endOffset = boundaries.second; - - return text(boundaries.first, boundaries.second); + return qt_accTextAfterOffsetHelper(*this, textCursor(), offset, boundaryType, startOffset, + endOffset); } QString QAccessibleTextWidget::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const { - Q_ASSERT(startOffset); - Q_ASSERT(endOffset); - - QTextCursor cursor = textCursor(); - cursor.setPosition(offset); - std::pair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType); - - *startOffset = boundaries.first; - *endOffset = boundaries.second; - - return text(boundaries.first, boundaries.second); + return qt_accTextAtOffsetHelper(*this, textCursor(), offset, boundaryType, startOffset, + endOffset); } void QAccessibleTextWidget::setCursorPosition(int position) diff --git a/src/widgets/accessible/rangecontrols.cpp b/src/widgets/accessible/rangecontrols.cpp index 741a1589851..c0de5357c9a 100644 --- a/src/widgets/accessible/rangecontrols.cpp +++ b/src/widgets/accessible/rangecontrols.cpp @@ -338,6 +338,22 @@ void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t) return QAccessibleWidgetV2::interface_cast(t); } +QList<QAccessible::Attribute> QAccessibleAbstractSlider::attributeKeys() const +{ + QList<QAccessible::Attribute> keys = QAccessibleWidgetV2::attributeKeys(); + keys.append(QAccessible::Attribute::Orientation); + + return keys; +} + +QVariant QAccessibleAbstractSlider::attributeValue(QAccessible::Attribute key) const +{ + if (key == QAccessible::Attribute::Orientation) + return QVariant::fromValue(abstractSlider()->orientation()); + + return QAccessibleWidgetV2::attributeValue(key); +} + QVariant QAccessibleAbstractSlider::currentValue() const { return abstractSlider()->value(); diff --git a/src/widgets/accessible/rangecontrols_p.h b/src/widgets/accessible/rangecontrols_p.h index 23482556f42..dd5a6a4531c 100644 --- a/src/widgets/accessible/rangecontrols_p.h +++ b/src/widgets/accessible/rangecontrols_p.h @@ -114,6 +114,10 @@ public: explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider); void *interface_cast(QAccessible::InterfaceType t) override; + // QAccessibleAttributesInterface + QList<QAccessible::Attribute> attributeKeys() const override; + QVariant attributeValue(QAccessible::Attribute key) const override; + // QAccessibleValueInterface QVariant currentValue() const override; void setCurrentValue(const QVariant &value) override; diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index b4ca17b9f64..25d742039c5 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -39,6 +39,7 @@ #include "qwindow.h" #include "private/qdialog_p.h" +#include "private/qcolorwell_p.h" #include <qpa/qplatformintegration.h> #include <qpa/qplatformservices.h> @@ -56,16 +57,12 @@ namespace QtPrivate { class QColorLuminancePicker; class QColorPicker; class QColorShower; -class QWellArray; -class QColorWell; class QColorPickingEventFilter; } // namespace QtPrivate using QColorLuminancePicker = QtPrivate::QColorLuminancePicker; using QColorPicker = QtPrivate::QColorPicker; using QColorShower = QtPrivate::QColorShower; -using QWellArray = QtPrivate::QWellArray; -using QColorWell = QtPrivate::QColorWell; using QColorPickingEventFilter = QtPrivate::QColorPickingEventFilter; class QColorDialogPrivate : public QDialogPrivate @@ -162,96 +159,6 @@ private: //////////// QWellArray BEGIN -namespace QtPrivate { - -class QWellArray : public QWidget -{ - Q_OBJECT - Q_PROPERTY(int selectedColumn READ selectedColumn) - Q_PROPERTY(int selectedRow READ selectedRow) - -public: - QWellArray(int rows, int cols, QWidget* parent=nullptr); - ~QWellArray() {} - QString cellContent(int row, int col) const; - - int selectedColumn() const { return selCol; } - int selectedRow() const { return selRow; } - - virtual void setCurrent(int row, int col); - virtual void setSelected(int row, int col); - - QSize sizeHint() const override; - - inline int cellWidth() const - { return cellw; } - - inline int cellHeight() const - { return cellh; } - - inline int rowAt(int y) const - { return y / cellh; } - - inline int columnAt(int x) const - { if (isRightToLeft()) return ncols - (x / cellw) - 1; return x / cellw; } - - inline int rowY(int row) const - { return cellh * row; } - - inline int columnX(int column) const - { if (isRightToLeft()) return cellw * (ncols - column - 1); return cellw * column; } - - inline int numRows() const - { return nrows; } - - inline int numCols() const - {return ncols; } - - inline QRect cellRect() const - { return QRect(0, 0, cellw, cellh); } - - inline QSize gridSize() const - { return QSize(ncols * cellw, nrows * cellh); } - - QRect cellGeometry(int row, int column) - { - QRect r; - if (row >= 0 && row < nrows && column >= 0 && column < ncols) - r.setRect(columnX(column), rowY(row), cellw, cellh); - return r; - } - - inline void updateCell(int row, int column) { update(cellGeometry(row, column)); } - -signals: - void selected(int row, int col); - void currentChanged(int row, int col); - void colorChanged(int index, QRgb color); - -protected: - virtual void paintCell(QPainter *, int row, int col, const QRect&); - virtual void paintCellContents(QPainter *, int row, int col, const QRect&); - - void mousePressEvent(QMouseEvent*) override; - void mouseReleaseEvent(QMouseEvent*) override; - void keyPressEvent(QKeyEvent*) override; - void focusInEvent(QFocusEvent*) override; - void focusOutEvent(QFocusEvent*) override; - void paintEvent(QPaintEvent *) override; - -private: - Q_DISABLE_COPY(QWellArray) - - int nrows; - int ncols; - int cellw; - int cellh; - int curRow; - int curCol; - int selRow; - int selCol; -}; - void QWellArray::paintEvent(QPaintEvent *e) { QRect r = e->rect(); @@ -476,11 +383,12 @@ void QWellArray::keyPressEvent(QKeyEvent* e) e->ignore(); // we don't accept the event return; } - -} // namespace QtPrivate +} //////////// QWellArray END +namespace QtPrivate { + // Event filter to be installed on the dialog while in color-picking mode. class QColorPickingEventFilter : public QObject { public: @@ -511,7 +419,7 @@ private: QColorDialogPrivate *m_dp; }; -} // unnamed namespace +} // namespace QtPrivate /*! Returns the number of custom colors supported by QColorDialog. All @@ -571,35 +479,6 @@ static inline void rgb2hsv(QRgb rgb, int &h, int &s, int &v) c.getHsv(&h, &s, &v); } -namespace QtPrivate { - -class QColorWell : public QWellArray -{ -public: - QColorWell(QWidget *parent, int r, int c, const QRgb *vals) - :QWellArray(r, c, parent), values(vals), mousePressed(false), oldCurrent(-1, -1) - { setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); } - -protected: - void paintCellContents(QPainter *, int row, int col, const QRect&) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseMoveEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; -#if QT_CONFIG(draganddrop) - void dragEnterEvent(QDragEnterEvent *e) override; - void dragLeaveEvent(QDragLeaveEvent *e) override; - void dragMoveEvent(QDragMoveEvent *e) override; - void dropEvent(QDropEvent *e) override; -#endif - -private: - const QRgb *values; - bool mousePressed; - QPoint pressPos; - QPoint oldCurrent; - -}; - void QColorWell::paintCellContents(QPainter *p, int row, int col, const QRect &r) { int i = row + col*numRows(); @@ -687,6 +566,8 @@ void QColorWell::mouseReleaseEvent(QMouseEvent *e) mousePressed = false; } +namespace QtPrivate { + class QColorPicker : public QFrame { Q_OBJECT diff --git a/src/widgets/dialogs/qcolorwell_p.h b/src/widgets/dialogs/qcolorwell_p.h new file mode 100644 index 00000000000..31d69fabb13 --- /dev/null +++ b/src/widgets/dialogs/qcolorwell_p.h @@ -0,0 +1,142 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QCOLORWELL_P_H +#define QCOLORWELL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qrect.h> +#include <QtWidgets/qwidget.h> + +QT_REQUIRE_CONFIG(colordialog); + +QT_BEGIN_NAMESPACE + +class QWellArray : public QWidget +{ + Q_OBJECT + Q_PROPERTY(int selectedColumn READ selectedColumn) + Q_PROPERTY(int selectedRow READ selectedRow) + +public: + QWellArray(int rows, int cols, QWidget *parent = nullptr); + ~QWellArray() { } + + int selectedColumn() const { return selCol; } + int selectedRow() const { return selRow; } + + virtual void setCurrent(int row, int col); + virtual void setSelected(int row, int col); + + QSize sizeHint() const override; + + inline int cellWidth() const { return cellw; } + + inline int cellHeight() const { return cellh; } + + inline int rowAt(int y) const { return y / cellh; } + + inline int columnAt(int x) const + { + if (isRightToLeft()) + return ncols - (x / cellw) - 1; + return x / cellw; + } + + inline int rowY(int row) const { return cellh * row; } + + inline int columnX(int column) const + { + if (isRightToLeft()) + return cellw * (ncols - column - 1); + return cellw * column; + } + + inline int numRows() const { return nrows; } + + inline int numCols() const { return ncols; } + + inline QRect cellRect() const { return QRect(0, 0, cellw, cellh); } + + inline QSize gridSize() const { return QSize(ncols * cellw, nrows * cellh); } + + QRect cellGeometry(int row, int column) + { + QRect r; + if (row >= 0 && row < nrows && column >= 0 && column < ncols) + r.setRect(columnX(column), rowY(row), cellw, cellh); + return r; + } + + inline void updateCell(int row, int column) { update(cellGeometry(row, column)); } + +signals: + void selected(int row, int col); + void currentChanged(int row, int col); + void colorChanged(int index, QRgb color); + +protected: + virtual void paintCell(QPainter *, int row, int col, const QRect &); + virtual void paintCellContents(QPainter *, int row, int col, const QRect &); + + void mousePressEvent(QMouseEvent *) override; + void mouseReleaseEvent(QMouseEvent *) override; + void keyPressEvent(QKeyEvent *) override; + void focusInEvent(QFocusEvent *) override; + void focusOutEvent(QFocusEvent *) override; + void paintEvent(QPaintEvent *) override; + +private: + Q_DISABLE_COPY(QWellArray) + + int nrows; + int ncols; + int cellw; + int cellh; + int curRow; + int curCol; + int selRow; + int selCol; +}; + +class QColorWell : public QWellArray +{ +public: + QColorWell(QWidget *parent, int r, int c, const QRgb *vals) + : QWellArray(r, c, parent), values(vals), mousePressed(false), oldCurrent(-1, -1) + { + setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); + } + +protected: + void paintCellContents(QPainter *, int row, int col, const QRect &) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; +#if QT_CONFIG(draganddrop) + void dragEnterEvent(QDragEnterEvent *e) override; + void dragLeaveEvent(QDragLeaveEvent *e) override; + void dragMoveEvent(QDragMoveEvent *e) override; + void dropEvent(QDropEvent *e) override; +#endif + +private: + const QRgb *values; + bool mousePressed; + QPoint pressPos; + QPoint oldCurrent; +}; + +QT_END_NAMESPACE + +#endif // QCOLORWELL_P_H diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index d964c9667e6..1ed9dd06e3c 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -3008,7 +3008,6 @@ void QFileDialogPrivate::createWidgets() qFileDialogUi->lookInCombo->setDuplicatesEnabled(false); // filename - qFileDialogUi->fileNameEdit->setFileDialogPrivate(this); #ifndef QT_NO_SHORTCUT qFileDialogUi->fileNameLabel->setBuddy(qFileDialogUi->fileNameEdit); #endif diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 15044cfd291..dd4a2505def 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -266,12 +266,9 @@ private: class QFileDialogLineEdit : public QLineEdit { public: - QFileDialogLineEdit(QWidget *parent = nullptr) : QLineEdit(parent), d_ptr(nullptr){} - void setFileDialogPrivate(QFileDialogPrivate *d_pointer) {d_ptr = d_pointer; } + QFileDialogLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) {} void keyPressEvent(QKeyEvent *e) override; bool hideOnEsc; -private: - QFileDialogPrivate *d_ptr; }; class QFileDialogComboBox : public QComboBox diff --git a/src/widgets/doc/images/designer-stylesheet-options.png b/src/widgets/doc/images/designer-stylesheet-options.png Binary files differdeleted file mode 100644 index a6893e770bc..00000000000 --- a/src/widgets/doc/images/designer-stylesheet-options.png +++ /dev/null diff --git a/src/widgets/doc/images/designer-stylesheet-options.webp b/src/widgets/doc/images/designer-stylesheet-options.webp Binary files differnew file mode 100644 index 00000000000..14d1ad368fc --- /dev/null +++ b/src/widgets/doc/images/designer-stylesheet-options.webp diff --git a/src/widgets/doc/images/designer-stylesheet-usage.png b/src/widgets/doc/images/designer-stylesheet-usage.png Binary files differdeleted file mode 100644 index f6875900def..00000000000 --- a/src/widgets/doc/images/designer-stylesheet-usage.png +++ /dev/null diff --git a/src/widgets/doc/images/designer-stylesheet-usage.webp b/src/widgets/doc/images/designer-stylesheet-usage.webp Binary files differnew file mode 100644 index 00000000000..79dd6803853 --- /dev/null +++ b/src/widgets/doc/images/designer-stylesheet-usage.webp diff --git a/src/widgets/doc/images/designer-validator-highlighter.png b/src/widgets/doc/images/designer-validator-highlighter.png Binary files differdeleted file mode 100644 index a6661d5c955..00000000000 --- a/src/widgets/doc/images/designer-validator-highlighter.png +++ /dev/null diff --git a/src/widgets/doc/images/designer-validator-highlighter.webp b/src/widgets/doc/images/designer-validator-highlighter.webp Binary files differnew file mode 100644 index 00000000000..7ca6cdf6eb3 --- /dev/null +++ b/src/widgets/doc/images/designer-validator-highlighter.webp diff --git a/src/widgets/doc/src/external-resources.qdoc b/src/widgets/doc/src/external-resources.qdoc index 17459b6a5bc..96117546a29 100644 --- a/src/widgets/doc/src/external-resources.qdoc +++ b/src/widgets/doc/src/external-resources.qdoc @@ -8,7 +8,7 @@ */ /*! - \externalpage http://www.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm + \externalpage https://rk.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm \title Sinclair Spectrum */ /*! diff --git a/src/widgets/doc/src/modelview.qdoc b/src/widgets/doc/src/modelview.qdoc index b2448a2c705..121cc30ed09 100644 --- a/src/widgets/doc/src/modelview.qdoc +++ b/src/widgets/doc/src/modelview.qdoc @@ -573,281 +573,10 @@ out of range when using ModelTest. - \section1 4. Good Sources of Additional Information - - \section2 4.1 Books - - Model/View programming is covered quite extensively in the documentation of - Qt but also in several good books. - - \list 1 - \li \b{C++ GUI Programming with Qt 4} / Jasmin Blanchette, Mark Summerfield, - \e{Prentice Hall, 2nd edition}, ISBN 0-13-235416-0. Also available in - German: \b{C++ GUI Programmierung mit Qt 4: Die offizielle Einführung}, - \e{Addison-Wesley}, ISBN 3-827327-29-6 - \li \b{The Book of Qt4, The Art of Building Qt Applications} / Daniel Molkentin, - \e{Open Source Press}, ISBN 1-59327-147-6. - Translated from \b{Qt 4, Einführung in die Applikationsentwicklung}, - \e{Open Source Press}, ISBN 3-937514-12-0. - \li \b{Foundations of Qt Development} / Johan Thelin, \e{Apress}, ISBN 1-59059-831-8. - \li \b{Advanced Qt Programming} / Mark Summerfield, \e{Prentice Hall}, ISBN 0-321-63590-6. - This book covers Model/View programming on more than 150 pages. - \endlist - - The following list provides an overview of example programs contained in the first three - books listed above. Some of them make very good templates for developing similar - applications. - - \table - \header - \li Example name - \li View class used - \li Model used - \li Aspects covered - \li - \row - \li Team Leaders - \li QListview - \li QStringListModel - \li - \li Book 1, Chapter 10, Figure 10.6 - \row - \li Color Names - \li QListView - \li QSortFilterProxyModel - applied to QStringListModel - \li - \li Book 1, Chapter 10, Figure 10.8 - \row - \li Currencies - \li QTableView - \li custom model based on - QAbstractTableModel - \li Read only - \li Book 1, Chapter 10, Figure 10.10 - \row - \li Cities - \li QTableView - \li Custom model based on - QAbstractTableModel - \li Read / write - \li Book 1, Chapter 10, Figure 10.12 - \row - \li Boolean Parser - \li QTreeView - \li Custom model based on - QAbstractItemModel - \li Read only - \li Book 1, Chapter 10, Figure 10.14 - \row - \li Track Editor - \li {2, 1} QTableWidget - \li Custom delegate providing a custom editor - \li Book 1, Chapter 10, Figure 10.15 - - \row - \li Address Book - \li QListView - QTableView - QTreeView - \li Custom model based on - QAbstractTableModel - \li Read / write - \li Book2, Chapter 8.4 - \row - \li Address Book with sorting - \li - \li QSortfilterProxyModel - \li Introducing sort and filter capabilities - \li Book2, Chapter 8.5 - \row - \li Address Book - with checkboxes - \li - \li - \li Introducing checkboxes in model/view - \li Book2, Chapter 8.6 - \row - \li Address Book with transposed grid - \li - \li Custom proxy Model based on QAbstractProxyModel - \li Introducing a custom model - \li Book2, Chapter 8.7 - \row - \li Address Book with drag and drop - \li - \li - \li Introducing drag and drop support - \li Book2, Chapter 8.8 - \row - \li Address Book with custom editor - \li - \li - \li Introducing custom delegates - \li Book2, Chapter 8.9 - \row - \li Views - \li QListView - QTableView - QTreeView - \li QStandardItemModel - \li Read only - \li Book 3, Chapter 5, figure 5-3 - \row - \li Bardelegate - \li QTableView - \li - \li Custom delegate for presentation based on QAbstractItemDelegate - \li Book 3, Chapter 5, figure 5-5 - \row - \li Editdelegate - \li QTableView - \li - \li Custom delegate for editing based on QAbstractItemDelegate - \li Book 3, Chapter 5, figure 5-6 - \row - \li Singleitemview - \li Custom view based on QAbstractItemView - \li - \li Custom view - \li Book 3, - Chapter 5, - figure 5-7 - \row - \li listmodel - \li QTableView - \li Custom Model based on QAbstractTableModel - \li Read only - \li Book 3, Chapter 5, Figure 5-8 - \row - \li treemodel - \li QTreeView - \li Custom Model based on QAbstractItemModel - \li Read only - \li Book 3, Chapter 5, Figure 5-10 - \row - \li edit integers - \li QListView - \li Custom Model based on QAbstractListModel - \li Read / write - \li Book 3, Chapter 5, Listing 5-37, Figure 5-11 - \row - \li sorting - \li QTableView - \li QSortFilterProxyModel applied to QStringListModel - \li Demonstrates sorting - \li Book 3, Chapter 5, Figure 5-12 - \endtable - - - \section2 4.2 Qt Documentation - - Qt 5.0 comes with 19 examples for model/view. - The examples can be found on the \l{Item Views Examples} page. - - \table - \header - \li Example name - \li View class used - \li Model used - \li Aspects covered - \row - \li Address Book - \li QTableView - \li QAbstractTableModel - QSortFilterProxyModel - \li Usage of QSortFilterProxyModel to generate different - subsets from one data pool - \row - \li Basic Sort/Filter Model - \li QTreeView - \li QStandardItemModel - QSortFilterProxyModel - \li - \row - \li Chart - \li Custom view - \li QStandardItemModel - \li Designing custom views that cooperate with selection models - \row - \li Color Editor Factory - \li {2, 1} QTableWidget - \li Enhancing the standard delegate with a new custom editor to choose colours - \row - \li Combo Widget Mapper - \li QDataWidgetMapper to map QLineEdit, QTextEdit and QComboBox - \li QStandardItemModel - \li Shows how a QComboBox can serve as a view class - \row - \li Custom Sort/Filter Model - \li QTreeView - \li QStandardItemModel - QSortFilterProxyModel - \li Subclass QSortFilterProxyModel for advanced sorting and filtering - \row - \li Dir View - \li QTreeView - \li QFileSystemModel - \li Very small example to demonstrate how to assign a model to a view - \row - \li Editable Tree Model - \li QTreeView - \li Custom tree model - \li Comprehensive example for working with trees, demonstrates - editing cells and tree structure with an underlying custom - model - \row - \li Fetch More - \li QListView - \li Custom list model - \li Dynamically changing model - \row - \li Frozen Column - \li QTableView - \li QStandardItemModel - \li - \row - \li Interview - \li Multiple - \li Custom item model - \li Multiple views - \row - \li Pixelator - \li QTableView - \li Custom table model - \li Implementation of a custom delegate - \row - \li Puzzle - \li QListView - \li Custom list model - \li Model/view with drag and drop - \row - \li Simple DOM Model - \li QTreeView - \li Custom tree model - \li Read only example for a custom tree model - \row - \li Simple Tree Model - \li QTreeView - \li Custom tree model - \li Read only example for a custom tree model - \row - \li Simple Widget Mapper - \li QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox - \li QStandardItemModel - \li Basic QDataWidgetMapper usage - \row - \li Spreadsheet - \li {2, 1} QTableView - \li Custom delegates - \row - \li Star Delegate - \li {2, 1} QTableWidget - \li Comprehensive custom delegate example. - \endtable + \section1 Examples - A \l{Model/View Programming}{reference document} for model/view technology - is also available. + Qt comes with multiple examples for model/view. You can find them on the + \l{Item Views Examples} page. */ /*! diff --git a/src/widgets/doc/src/qtwidgets-examples.qdoc b/src/widgets/doc/src/qtwidgets-examples.qdoc index 45677c471ba..364c985b310 100644 --- a/src/widgets/doc/src/qtwidgets-examples.qdoc +++ b/src/widgets/doc/src/qtwidgets-examples.qdoc @@ -164,3 +164,15 @@ regular expressions for the Widget-based applications. */ +/*! + \group examples-user-input + \ingroup all-examples + \title User Input Examples + \brief Using user input in Qt Widgets applications. + + \image imagegestures-example.png {Application handling touch gestures} + + Qt provides the functionality for handling user input and drag-and-drop in + widget-based applications. + +*/ diff --git a/src/widgets/doc/src/qtwidgets-toc.qdoc b/src/widgets/doc/src/qtwidgets-toc.qdoc index bc447b8bd58..beddf853a22 100644 --- a/src/widgets/doc/src/qtwidgets-toc.qdoc +++ b/src/widgets/doc/src/qtwidgets-toc.qdoc @@ -53,6 +53,7 @@ \li \l{Rich Text Examples} \li \l{Graphics View Examples} \li \l{Widget Tools Examples} + \li \l{User Input Examples} \endlist \endlist diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index 841948b671f..84226fdb5b5 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -536,21 +536,20 @@ to preview style sheets. You can right-click on any widget in Designer and select \uicontrol{Change styleSheet...} to set the style sheet. - \image designer-stylesheet-options.png + \image designer-stylesheet-options.webp {Editing a form in Qt Widgets Designer} - In Qt 4.2 and later, \QD also includes a - style sheet syntax highlighter and validator. The validator indicates - if the syntax is valid or invalid, at the bottom left of the \uicontrol{Edit - Style Sheet} dialog. + \QD also includes a style sheet syntax highlighter and validator. The + validator indicates if the syntax is valid or invalid, at the bottom left + of the \uicontrol{Edit Style Sheet} dialog. - \image designer-validator-highlighter.png + \image designer-validator-highlighter.webp {Editing and validating a stylesheet} When you click \uicontrol{OK} or \uicontrol{Apply}, \QD will automatically display the widget with its new stylesheet. - \image designer-stylesheet-usage.png + \image designer-stylesheet-usage.webp {Preview of a form with the new stylesheet} */ diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 51aea4079a1..6288aae096a 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -3108,7 +3108,8 @@ void QAbstractItemView::keyboardSearch(const QString &search) QModelIndex startMatch; QModelIndexList previous; do { - match = d->model->match(current, Qt::DisplayRole, d->keyboardInput); + match = d->model->match(current, Qt::DisplayRole, d->keyboardInput, 1, + d->keyboardSearchFlags); if (match == previous) break; firstMatch = match.value(0); @@ -3251,6 +3252,30 @@ void QAbstractItemView::setUpdateThreshold(int threshold) } /*! + \property QAbstractItemView::keyboardSearchFlags + \since 6.11 + This property determines how the default implementation of + keyboardSearch() matches the given string against the model's data. + + The default value is \c{Qt::MatchStartsWith|Qt::MatchWrap}. + + \sa keyboardSearch() + \sa QAbstractItemModel::match() +*/ + +Qt::MatchFlags QAbstractItemView::keyboardSearchFlags() const +{ + Q_D(const QAbstractItemView); + return d->keyboardSearchFlags; +} + +void QAbstractItemView::setKeyboardSearchFlags(Qt::MatchFlags searchFlags) +{ + Q_D(QAbstractItemView); + d->keyboardSearchFlags = searchFlags; +} + +/*! Opens a persistent editor on the item at the given \a index. If no editor exists, the delegate will create a new editor. diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h index 63adac8d6f2..ce509dc9e98 100644 --- a/src/widgets/itemviews/qabstractitemview.h +++ b/src/widgets/itemviews/qabstractitemview.h @@ -48,6 +48,8 @@ class Q_WIDGETS_EXPORT QAbstractItemView : public QAbstractScrollArea Q_PROPERTY(ScrollMode horizontalScrollMode READ horizontalScrollMode WRITE setHorizontalScrollMode RESET resetHorizontalScrollMode) Q_PROPERTY(int updateThreshold READ updateThreshold WRITE setUpdateThreshold) + Q_PROPERTY(Qt::MatchFlags keyboardSearchFlags READ keyboardSearchFlags + WRITE setKeyboardSearchFlags) public: enum SelectionMode { @@ -182,6 +184,9 @@ public: int updateThreshold() const; void setUpdateThreshold(int threshold); + Qt::MatchFlags keyboardSearchFlags() const; + void setKeyboardSearchFlags(Qt::MatchFlags searchFlags); + void openPersistentEditor(const QModelIndex &index); void closePersistentEditor(const QModelIndex &index); bool isPersistentEditorOpen(const QModelIndex &index) const; @@ -204,7 +209,7 @@ public: virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const override; - using QAbstractScrollArea::update; + using QWidget::update; public Q_SLOTS: virtual void reset(); diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index b24b2d21c33..60799fb8a50 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -383,6 +383,7 @@ public: QString keyboardInput; QElapsedTimer keyboardInputTime; + Qt::MatchFlags keyboardSearchFlags = Qt::MatchStartsWith | Qt::MatchWrap; bool autoScroll; QBasicTimer autoScrollTimer; diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index da1fbbd60df..84ff04c9f34 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1030,7 +1030,8 @@ void QTreeView::keyboardSearch(const QString &search) searchFrom = searchFrom.sibling(searchFrom.row(), start.column()); if (searchFrom.parent() == start.parent()) searchFrom = start; - QModelIndexList match = d->model->match(searchFrom, Qt::DisplayRole, searchString); + QModelIndexList match = d->model->match(searchFrom, Qt::DisplayRole, searchString, 1, + keyboardSearchFlags()); if (match.size()) { int hitIndex = d->viewIndex(match.at(0)); if (hitIndex >= 0 && hitIndex < startIndex) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 53ce4dd8211..fa95a1d2538 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1508,11 +1508,15 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) return; } - if (focus && (reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason) - && qt_in_tab_key_event) - focus->window()->setAttribute(Qt::WA_KeyboardFocusChange); - else if (focus && reason == Qt::ShortcutFocusReason) { - focus->window()->setAttribute(Qt::WA_KeyboardFocusChange); + if (focus) { + if ((reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason) + && qt_in_tab_key_event) + focus->window()->setAttribute(Qt::WA_KeyboardFocusChange); + else if (reason == Qt::ShortcutFocusReason) { + focus->window()->setAttribute(Qt::WA_KeyboardFocusChange); + } else { + focus->window()->setAttribute(Qt::WA_KeyboardFocusChange, false); + } } QWidget *prev = focus_widget; focus_widget = focus; diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 82d16cb1252..b2cfb27e814 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3419,29 +3419,28 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC } QRect gr = subControlRect(cc, opt, SC_SliderGroove, w); - if (slider->subControls & SC_SliderGroove) { + if (slider->subControls & SC_SliderGroove) grooveSubRule.drawRule(p, gr); - } if (slider->subControls & SC_SliderHandle) { QRect hr = subControlRect(cc, opt, SC_SliderHandle, w); - QRenderRule subRule1 = renderRule(w, opt, PseudoElement_SliderSubPage); - if (subRule1.hasDrawable()) { - QRect r(gr.topLeft(), - slider->orientation == Qt::Horizontal - ? QPoint(hr.x()+hr.width()/2, gr.y()+gr.height() - 1) - : QPoint(gr.x()+gr.width() - 1, hr.y()+hr.height()/2)); - subRule1.drawRule(p, r); - } - - QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderAddPage); - if (subRule2.hasDrawable()) { - QRect r(slider->orientation == Qt::Horizontal - ? QPoint(hr.x()+hr.width()/2+1, gr.y()) - : QPoint(gr.x(), hr.y()+hr.height()/2+1), - gr.bottomRight()); - subRule2.drawRule(p, r); + if (slider->subControls & SC_SliderGroove) { + const bool isHor = slider->orientation == Qt::Horizontal; + QRenderRule subRule1 = renderRule(w, opt, PseudoElement_SliderSubPage); + if (subRule1.hasDrawable()) { + QRect r(gr.topLeft(), + isHor ? QPoint(hr.x() + hr.width() / 2, gr.y() + gr.height() - 1) + : QPoint(gr.x() + gr.width() - 1, hr.y() + hr.height() / 2)); + subRule1.drawRule(p, r); + } + QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderAddPage); + if (subRule2.hasDrawable()) { + QRect r(isHor ? QPoint(hr.x() + hr.width() / 2 + 1, gr.y()) + : QPoint(gr.x(), hr.y() + hr.height() / 2 + 1), + gr.bottomRight()); + subRule2.drawRule(p, r); + } } handleSubRule.drawRule(p, handleSubRule.boxRect(hr, Margin)); diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 9b06822c218..b9143a59ee7 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -851,6 +851,12 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, } #ifndef QT_NO_FRAME case PE_Frame: + if (w && w->inherits("QComboBoxPrivateContainer")){ + QStyleOption copy = *opt; + copy.state |= State_Raised; + proxy()->drawPrimitive(PE_PanelMenu, ©, p, w); + break; + } case PE_FrameMenu: if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) { if (frame->lineWidth == 2 || pe == PE_Frame) { @@ -873,6 +879,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, } } else { QPalette popupPal = opt->palette; + p->drawRect(opt->rect); popupPal.setColor(QPalette::Light, opt->palette.window().color()); popupPal.setColor(QPalette::Midlight, opt->palette.light().color()); qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken); @@ -899,6 +906,12 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, p->drawRect(opt->rect); } break; } + case PE_PanelMenu: + if (w && w->inherits("QComboBoxPrivateContainer")){ + const QBrush menuBackground = opt->palette.base().color(); + QColor borderColor = opt->palette.window().color(); + qDrawPlainRect(p, opt->rect, borderColor, 1, &menuBackground); + } case PE_FrameWindow: { QPalette popupPal = opt->palette; popupPal.setColor(QPalette::Light, opt->palette.window().color()); diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index 1ca6b8a47a1..7aff0da3327 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -2220,7 +2220,7 @@ QMdiSubWindow::QMdiSubWindow(QWidget *parent, Qt::WindowFlags flags) d->titleBarPalette = d->desktopPalette(); d->font = QApplication::font("QMdiSubWindowTitleBar"); // We don't want the menu icon by default on mac. -#ifndef Q_OS_MAC +#ifndef Q_OS_DARWIN if (windowIcon().isNull()) d->menuIcon = style()->standardIcon(QStyle::SP_TitleBarMenuButton, nullptr, this); else @@ -2847,8 +2847,11 @@ bool QMdiSubWindow::event(QEvent *event) break; case QEvent::WindowIconChange: d->menuIcon = windowIcon(); + // We don't want the default menu icon on mac. +#ifndef Q_OS_DARWIN if (d->menuIcon.isNull()) d->menuIcon = style()->standardIcon(QStyle::SP_TitleBarMenuButton, nullptr, this); +#endif if (d->controlContainer) d->controlContainer->updateWindowIcon(d->menuIcon); if (!maximizedSystemMenuIconWidget()) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 7d4228709be..92ff14dd44f 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -771,7 +771,8 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason #endif hideMenu(hideActiveMenu); } else if (!currentAction || !currentAction->menu()) { - sloppyState.startTimerIfNotRunning(); + if (reason != SelectionReason::SelectedFromAPI) + sloppyState.startTimerIfNotRunning(); } } } @@ -2172,7 +2173,7 @@ void QMenu::hideTearOffMenu() void QMenu::setActiveAction(QAction *act) { Q_D(QMenu); - d->setCurrentAction(act, 0); + d->setCurrentAction(act, 0, QMenuPrivate::SelectionReason::SelectedFromAPI); if (d->scroll && act) d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollCenter); } @@ -2971,7 +2972,7 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e) #endif d->activateAction(action, QAction::Trigger); } - } else if (!action || action->isEnabled()) { + } else if (!action || (action->isEnabled() && !action->isSeparator())) { d->hideUpToMenuBar(); } } diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index dd1f058a288..d9dcd7d0362 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -362,7 +362,8 @@ public: } delayState; enum SelectionReason { SelectedFromKeyboard, - SelectedFromElsewhere + SelectedFromAPI, + SelectedFromElsewhere, }; enum class SelectionDirection { Up, |
