📄 qlistview.cpp
字号:
return QMAX( w, QApplication::globalStrut().width() );}/*! Paints a focus indication on the rectangle \a r using painter \a p and colors \a cg. \a p is already clipped. \sa paintCell() paintBranches() QListView::setAllColumnsShowFocus()*/void QListViewItem::paintFocus( QPainter *p, const QColorGroup &cg, const QRect & r ){ listView()->style().drawFocusRect( p, r, cg, isSelected()? & cg.highlight() : & cg.base(), isSelected() );}/*! Paints a set of branches from this item to (some of) its children. \a p is set up with clipping and translation so that you can draw only in the rectangle you need to; \a cg is the color group to use; the update rectangle is at 0, 0 and has size \a w, \a h. The top of the rectangle you own is at \a y (which is never greater than 0 but can be outside the window system's allowed coordinate range). The update rectangle is in an undefined state when this function is called; this function must draw on \e all of the pixels. \sa paintCell(), QListView::drawContentsOffset()*/void QListViewItem::paintBranches( QPainter * p, const QColorGroup & cg, int w, int y, int h, GUIStyle s ){ listView()->paintEmptyArea( p, QRect( 0, 0, w, h ) ); QListViewItem * child = firstChild(); int linetop = 0, linebot = 0; int dotoffset = (itemPos() + height() - y) %2; // each branch needs at most two lines, ie. four end points QPointArray dotlines( childCount() * 4 ); int c = 0; // skip the stuff above the exposed rectangle while ( child && y + child->height() <= 0 ) { y += child->totalHeight(); child = child->nextSibling(); } int bx = w / 2; // paint stuff in the magical area while ( child && y < h ) { linebot = y + child->height()/2; if ( (child->expandable || child->childCount()) && (child->height() > 0) ) { // needs a box p->setPen( cg.text() ); p->drawRect( bx-4, linebot-4, 9, 9 );// p->setPen( cg.text() ); // ### windows uses black if ( s == WindowsStyle ) { // plus or minus p->drawLine( bx - 2, linebot, bx + 2, linebot ); if ( !child->isOpen() ) p->drawLine( bx, linebot - 2, bx, linebot + 2 ); } else { QPointArray a; if ( child->isOpen() ) a.setPoints( 3, bx-2, linebot-2, bx, linebot+2, bx+2, linebot-2 ); //RightArrow else a.setPoints( 3, bx-2, linebot-2, bx+2, linebot, bx-2, linebot+2 ); //DownArrow p->setBrush( cg.text() ); p->drawPolygon( a ); p->setBrush( NoBrush ); } // dotlinery dotlines[c++] = QPoint( bx, linetop ); dotlines[c++] = QPoint( bx, linebot - 5 ); dotlines[c++] = QPoint( bx + 5, linebot ); dotlines[c++] = QPoint( w, linebot ); linetop = linebot + 5; } else { // just dotlinery dotlines[c++] = QPoint( bx+1, linebot ); dotlines[c++] = QPoint( w, linebot ); } y += child->totalHeight(); child = child->nextSibling(); } if ( child ) // there's a child, so move linebot to edge of rectangle linebot = h; if ( linetop < linebot ) { dotlines[c++] = QPoint( bx, linetop ); dotlines[c++] = QPoint( bx, linebot ); } p->setPen( cg.dark() ); if ( s == WindowsStyle ) { if ( !verticalLine ) { // make 128*1 and 1*128 bitmaps that can be used for // drawing the right sort of lines. verticalLine = new QBitmap( 1, 129, TRUE ); horizontalLine = new QBitmap( 128, 1, TRUE ); QPointArray a( 64 ); QPainter p; p.begin( verticalLine ); int i; for( i=0; i<64; i++ ) a.setPoint( i, 0, i*2+1 ); p.setPen( color1 ); p.drawPoints( a ); p.end(); QApplication::flushX(); verticalLine->setMask( *verticalLine ); p.begin( horizontalLine ); for( i=0; i<64; i++ ) a.setPoint( i, i*2+1, 0 ); p.setPen( color1 ); p.drawPoints( a ); p.end(); QApplication::flushX(); horizontalLine->setMask( *horizontalLine ); qAddPostRoutine( cleanupBitmapLines ); } int line; // index into dotlines for( line = 0; line < c; line += 2 ) { // assumptions here: lines are horizontal or vertical. // lines always start with the numerically lowest // coordinate. // point ... relevant coordinate of current point // end ..... same coordinate of the end of the current line // other ... the other coordinate of the current point/line if ( dotlines[line].y() == dotlines[line+1].y() ) { int end = dotlines[line+1].x(); int point = dotlines[line].x(); int other = dotlines[line].y(); while( point < end ) { int i = 128; if ( i+point > end ) i = end-point; p->drawPixmap( point, other, *horizontalLine, 0, 0, i, 1 ); point += i; } } else { int end = dotlines[line+1].y(); int point = dotlines[line].y(); int other = dotlines[line].x(); int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0; while( point < end ) { int i = 128; if ( i+point > end ) i = end-point; p->drawPixmap( other, point, *verticalLine, 0, pixmapoffset, 1, i ); point += i; } } } } else { int line; // index into dotlines p->setPen( cg.text() ); for( line = 0; line < c; line += 2 ) { p->drawLine( dotlines[line].x(), dotlines[line].y(), dotlines[line+1].x(), dotlines[line+1].y() ); } }}QListViewPrivate::Root::Root( QListView * parent ) : QListViewItem( parent ){ lv = parent; setHeight( 0 ); setOpen( TRUE );}void QListViewPrivate::Root::setHeight( int ){ QListViewItem::setHeight( 0 );}void QListViewPrivate::Root::invalidateHeight(){ QListViewItem::invalidateHeight(); lv->triggerUpdate();}QListView * QListViewPrivate::Root::theListView() const{ return lv;}void QListViewPrivate::Root::setup(){ // explicitly nothing}/*! \fn void QListView::onItem( QListViewItem *i ) This signal is emitted, when the user moves the mouse cursor onto an item. It磗 only emitted once per item.*//*! \fn void QListView::onViewport() This signal is emitted, when the user moves the mouse cursor, which was on an item away from the item onto the viewport.*//*! \enum QListView::SelectionMode This enumerated type is used by QListView to indicate how it reacts to selection by the user. It has four values: <ul> <li> \c Single - When the user selects an item, any already-selected item becomes unselected, and the user cannot unselect the selected item. This means that the user can never clear the selection, even though the selection may be cleared by the application programmer using QListView::clearSelection(). <li> \c Multi - When the user selects an item in the most ordinary way, the selection status of that item is toggled and the other items are left alone. <li> \c Extended - When the user selects an item in the most ordinary way, the selection is cleared and the new item selected. However, if the user presses the CTRL key when clicking on an item, the clicked item gets toggled and all other items are left untouched. And if the user presses the SHIFT key while clicking on an item, all items between the current item and the clicked item get selected or unselected depending on the state of the clicked item. Also multiple items can be selected by dragging the mouse while the left mouse button stayes pressed. <li> \c NoSelection - Items cannot be selected. </ul> In other words, \c Single is a real single-selection listview, \c Multi a real multi-selection listview, and \c Extended listview where users can select multiple items but usually want to select either just one or a range of contiguous items, and \c NoSelection is for a listview where the user can look but not touch.*//*! \class QListView qlistview.h \brief The QListView class implements a list/tree view. \ingroup advanced It can display and control a hierarchy of multi-column items, and provides the ability to add new items at any time, let the user select one or many items, sort the list in increasing or decreasing order by any column, and so on. The simplest mode of usage is to create a QListView, add some column headers using addColumn(), create one or more QListViewItem objects with the QListView as parent, set up the list view's geometry(), and show() it. The main setup functions are <ul> <li>addColumn() - adds a column, with text and perhaps width. <li>setColumnWidthMode() - sets the column to be resized automatically or not. <li>setAllColumnsShowFocus() - decides whether items should show keyboard focus using all columns, or just column 0. The default is to show focus using just column 0. <li>setRootIsDecorated() - decides whether root items can be opened and closed by the user, and have open/close decoration to their left. The default is FALSE. <li>setTreeStepSize() - decides the how many pixels an item's children are indented relative to their parent. The default is 20. This is mostly a matter of taste. <li>setSorting() - decides whether the items should be sorted, whether it should be in ascending or descending order, and by what column it should be sorted.</ul> To handle events such as mouse-presses on the listview, derived classes can reimplement the QScrollView functions\link QScrollView::contentsMousePressEvent() contentsMousePressEvent\endlink,\link QScrollView::contentsMouseReleaseEvent() contentsMouseReleaseEvent\endlink,\link QScrollView::contentsMouseDoubleClickEvent() contentsMouseDoubleClickEvent\endlink,\link QScrollView::contentsMouseMoveEvent() contentsMouseMoveEvent\endlink,\link QScrollView::contentsDragEnterEvent() contentsDragEnterEvent\endlink,\link QScrollView::contentsDragMoveEvent() contentsDragMoveEvent\endlink,\link QScrollView::contentsDragLeaveEvent() contentsDragLeaveEvent\endlink,\link QScrollView::contentsDropEvent() contentsDropEvent\endlink, and\link QScrollView::contentsWheelEvent() contentsWheelEvent\endlink. There are also several functions for mapping between items and coordinates. itemAt() returns the item at a position on-screen, itemRect() returns the rectangle an item occupies on the screen and itemPos() returns the position of any item (not on-screen, in the list view). firstChild() returns the item at the top of the view (not necessarily on-screen) so you can iterate over the items using either QListViewItem::itemBelow() or a combination of QListViewItem::firstChild() and QListViewItem::nextSibling(). Naturally, QListView provides a clear() function, as well as an explicit insertItem() for when QListViewItem's default insertion won't do. There is a variety of selection modes, described in the QListView::SelectionMode documentation. The default is single-selection, and you can change it using setSelectionMode(). For compatibility with previous Qt versions there is still the setMultiSelection() methode. Calling setMultiSelection( TRUE ) is equivalent to setSelectionMode( Multi ), and setMultiSelection( FALSE ) is equivalent to setSelectionMode( Single ). It's suggested not to use setMultiSelection() anymore, but to use setSelectionMode() instead. Since QListView offers multiple selection it has to display keyboard focus and selection state separately. Therefore there are functions both to set the selection state of an item, setSelected(), and to select which item displays keyboard focus, setCurrentItem(). QListView emits two groups of signals: One group signals changes in selection/focus state and one signals selection. The first group consists of selectionChanged(), applicable to all list views, and selectionChanged( QListViewItem * ), applicable only to single-selection list view, and currentChanged( QListViewItem * ). The second group consists of doubleClicked( QListViewItem * ), returnPressed( QListViewItem * ) and rightButtonClicked( QListViewItem *, const QPoint&, int ), etc. In Motif style, QListView deviates fairly strongly from the look and feel of the Motif hierarchical tree view. This is done mostly to provide a usable keyboard interface and to make the list view look better with a white background. \warning The list view assumes ownership of all list view items and will delete them when it does not need them any more. <img src=qlistview-m.png> <img src=qlistview-w.png> \internal need to say stuff about the mouse and keyboard interface.*//*! Constructs a new empty list view, with \a parent as a parent and \a name as object name. Performance is boosted by modifying the widget flags \a f so that only part of the QListViewItem children is redrawn. This may be unsuitable for custom QListViewItem classes, in which case \c WNorthWestGravity and \c WRepaintNoErase should be cleared. \sa QWidget::clearWFlags() Qt::WidgetFlags*/QListView::QListView( QWidget * parent, const char *name, WFlags f ) : QScrollView( parent, name, f | WNorthWestGravity | WRepaintNoErase ){ init();}/*! Constructs a new empty list view, with \a parent as a parent and \a name as object name. Performance is boosted by modifying the widget flags so that only part of the QListViewItem children is redrawn. This may be unsuitable for custom QListViewItem classes, in which case \c WNorthWestGravity and \c WRepaintNoErase should be cleared. \sa QWidget::clearWFlags() Qt::WidgetFlags*/QListView::QListView( QWidget * parent, const char *name ) : QScrollView( parent, name, WNorthWestGravity | WRepaintNoErase ){ init();}void QListView::init(){ d = new QListViewPrivate; d->vci = 0; d->timer = new QTimer( this ); d->levelWidth = 20; d->r = 0; d->rootIsExpandable = 0; d->h = new QHeader( this, "list view header" ); d->h->installEventFilter( this ); d->focusItem = 0; d->drawables = 0; d->dirtyItems = 0; d->dirtyItemTimer = new QTimer( this ); d->visibleTimer = new QTimer( this ); d->margin = 1; d->selectionMode = QListView::Single; d->sortcolumn = 0; d->ascending = TRUE; d->allColumnsShowFocus = FALSE; d->fontMetricsHeight = fontMetrics().height(); d->h->setTracking(TRUE); d->buttonDown = FALSE; d->ignoreDoubleClick = FALSE; d->column.setAutoDelete( TRUE ); d->iterators = 0; d->scrollTimer = 0; d->sortIndicator = FALSE; d->clearing = FALSE; d->minLeftBearing = fontMetrics().minLeftBearing(); d->minRightBearing = fontMetrics().minRightBearing(); d->highlighted = 0; d->pressedItem = 0; d->selectAnchor = 0; d->select = TRUE; d->useDoubleBuffer = FALSE; setMouseTracking( TRUE ); viewport()->setMouseTracking( TRUE ); connect( d->timer, SIGNAL(timeout()), this, SLOT(updateContents()) ); connect( d->dirtyItemTimer, SIGNAL(timeout()), this, SLOT(updateDirtyItems()) ); connect( d->visibleTimer, SIGNAL(timeout()), this, SLOT(makeVisible()) ); connect( d->h, SIGNAL(sizeChange(int,int,int)), this, SLOT(handleSizeChange(int,int,int)) ); connect( d->h, SIGNAL(moved(int,int)), this, SLOT(triggerUpdate()) ); connect( d->h, SIGNAL(sectionClicked(int)), this, SLOT(changeSortColumn(int)) ); connect( horizontalScrollBar(), SIGNAL(sliderMoved(int)), d->h, SLOT(setOffset(int)) ); connect( horizontalScrollBar(), SIGNAL(valueChanged(int)), d->h, SLOT(setOffset(int)) ); // will access d->r QListViewPrivate::Root * r = new QListViewPrivate::Root( this ); r->is_root = TRUE; d->r = r; d->r->setSelectable( FALSE ); viewport()->setFocusProxy( this ); viewport()->setFocusPolicy( WheelFocus ); viewport()->setBackgroundMode( PaletteBase );#ifdef QT_KEYPAD_MODE if( qt_modalEditingEnabled ) installEventFilter(this);#endif}/*! If \a show is TRUE, draw an arrow in the header of the listview to indicate the sort order of the listview contents. The arrow will be drawn in the correct column and will point to the correct direction. Set \a show to FALSE to disable this feature.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -