默认情况下 QListView 会遍历所有项查询一些信息,如 size 等(QML ListView 默认是不会全部遍历的),可以设置 uniformItemSizes(true), 提示所有项目具有相同的大小,这样 QListView 会取最后一项的 size 来作为所有项的 size,而不可见区域不会再去遍历。但是遇到大量数据且 size 不一致的情况就没法了。
相关源码片段:
void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
{
//... ...
for (int row = info.first; row sizeHint(option, index) : QSize();
}
if (!cachedItemSize.isValid()) { // the last item is probaly the largest, so we use its size
int row = model->rowCount(root) - 1;
QModelIndex sample = model->index(row, column, root);
const QAbstractItemDelegate *delegate = delegateForIndex(sample);
cachedItemSize = delegate ? delegate->sizeHint(option, sample) : QSize();
}
return cachedItemSize;
}
参照文档:https://doc.qt.io/qt-5/qlistview.html
二、Qt Quick 问题交流 1.TextInput 及 TextField 的 editingFinished 信号通过查看 Qt 源码可以发现,输入框在两种情况下会触发编辑结束信号:按 Enter 或者 Return 键,或者失去焦点后。
问题1,按回车触发的编辑结束不会使编辑框失去焦点,光标还是在原地闪烁。当 focus 为 false 时,编辑框就失去焦点,光标也就不显示了。
如果直接在 editingFinished 事件处理函数里写 focus = false,那么会触发两次 editingFinished 。(回车触发一次,失去焦点触发一次)
onEditingFinished: { focus = false; }
可以自己处理按键事件,再去设置 focus = false,这样回车时即触发了 finish,也不再显示光标。
Keys.enabled: true
Keys.onReturnPressed: focus = false;
Keys.onEnterPressed: focus = false;
Keys.onReleased: event.accepted = (event.key===Qt.Key_Enter || event.key===Qt.Key_Return);
问题2,如果设置了 validator,再清空编辑框后回车或者切换焦点,不会触发 editingFinished,因为设置 mask 或者 validator 后,源码有个 hasAcceptableInput 函数判断,内容为空时 acceptableInput 也为 false 了,此时不会进入 emit editingFinished 的逻辑。但是我们可以判断 acceptableInput 为 false 时,主动触发 editingFinished 信号。
TextInput {
anchors.fill: parent
verticalAlignment: TextInput.AlignVCenter
selectByMouse: true
validator: IntValidator{ bottom: 0; top: 100; }
onEditingFinished: {
console.log('onEditingFinished 1', text, '-', cursorVisible, focus, activeFocus)
if(focus){
//focus = false
console.log('focus', text)
}else{
console.log('finish', text)
}
console.log('onEditingFinished 2', text, '-', cursorVisible, focus, activeFocus)
}
Keys.enabled: true
Keys.onReturnPressed: {
console.log('onReturnPressed', text)
event.accepted = true;
focus = false;
}
Keys.onEnterPressed: {
console.log('onEnterPressed', text)
event.accepted = true;
focus = false;
}
Keys.onReleased: {
event.accepted = (event.key===Qt.Key_Enter || event.key===Qt.Key_Return);
}
onCursorVisibleChanged: {
console.log('onCursorVisibleChanged', cursorVisible, focus, activeFocus)
if(cursorVisible){
selectAll();
}else{
if(!acceptableInput){ //带validator时为空的输入也触发finish
editingFinished();
}
}
}
onActiveFocusChanged: {
console.log('onActiveFocusChanged', cursorVisible, focus, activeFocus)
focus = activeFocus; //使切换窗口后回来不显示光标
}
}
三、其他
1.QAxObject.setControl 设置 Office 和 WPS 对应组件
WPS文字-------KWPS.Aplication
WPS的Excel----KET.Application
WPS的演示文档--KWPP.Application
Word----------Word.Application
Excel---------Excel.Application
Powerpoint----Powerpoint.Application