从选项卡视图获取活动选项卡并更改项目属性



在双窗格文件管理器的上下文中,我有两个并排的TabView项目,每个项目当然包含多个选项卡,每个Tab加载一个TableView,使用 FolderListModel 显示特定目录的内容。

SplitView
    TabView
        Tab
        Tab
    TabView
        Tab

我目前的任务是实现一个工具栏按钮来切换活动选项卡中显示的FolderListModel实例的 showHidden 属性。因此,我需要一种方法来找出当前活动的选项卡是什么。

接下来,一旦我得到活动Tab,我需要更改Tab.item.some_property,特别是感兴趣的属性是show_hidden,它是底层FolderListModelshowHidden属性的别名。例如,硬编码方案为:

ToolButton {
    onClicked: {
        tab1.item.show_hidden = false;
        tab1.destroy();  // need "refresh" instead
    }
}

首先我需要根据它是否处于活动状态来获取tab1,其次,在我更改show_hidden后,视图不会自行刷新,所以我需要调用某种重新加载函数,但是哪个呢?或者也许重新加载不是最好的方法?是否可以使用自定义信号处理程序来执行此操作?(同样,我只能在概念上思考,而不知道如何实现它。

正如建议的那样,我在下面发布一个运行示例:

/* main.qml */
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
ApplicationWindow {
    visible: true
    width: 1280
    height: 700
    toolBar: ToolBar {
        RowLayout {
            anchors.fill: parent
            ToolButton {
                onClicked: {    // TODO toggle folderModel.showHidden property
                    tab1A.item.show_hidden = false;
//                    tab1A.destroy();  // fixme how to refresh the view?
                }
            }
        }
    }
    Item {
        anchors.fill: parent
        SplitView {
            id: splitView
            anchors.fill: parent
            TabView {
                id: tabView1
                width: splitView.width / 2
                Tab {
                    id: tab1A
                    title: qsTr("Home")
                    source: "dirview.qml"
                    onLoaded: {
                        item.folder_url = "file:///tmp";
                    }
                }
                Tab {
                    title: qsTr("Folder")
                    source: "dirview.qml"
                    onLoaded: {
                        item.folder_url = "file:///home";
                    }
                }
            }
            TabView {
                id: tabView2
                Tab {
                    title: qsTr("Home")
                    source: "dirview.qml"
                    onLoaded: {
                        item.folder_url = "file:///home";
                    }
                }
            }
        }
    }
}

/* dirview.qml */
import QtQuick 2.4
import QtQuick.Controls 1.4
import Qt.labs.folderlistmodel 2.1
TableView {
    property alias folder_url: folderModel.folder
    property alias show_hidden: folderModel.showHidden
    id: tableView
    anchors.fill: parent
    TableViewColumn {
        role: "fileName"
        title: qsTr("Name")
        width: tableView.width * 0.7
    }
    TableViewColumn {
        role: "fileSize"
        title: qsTr("Size")
        width: tableView.width * 0.2
    }
    FolderListModel {
        id: folderModel
        nameFilters: ["*"]
        showHidden: true
        showDirsFirst: true
        showDotAndDotDot: true
    }
    model: folderModel
}

谢谢。


注意到一些奇怪的事情:Tab.item.folder_url有正确的信息,但是,Tab.item.show_hidden总是false,即使我删除了手动将其设置为 false 的行。这很难理解,因为我最初将FolderListModel.showHidden设置为dirview.qml true

ToolButton {
    onClicked: {    // TODO toggle folderModel.showHidden property
        var cur_tab_idx = tabView1.currentIndex;
        console.log(tabView1.getTab(cur_tab_idx).item.folder_url);
        console.log(tabView1.getTab(cur_tab_idx).item.show_hidden);
    }
}

以下是我如何让它工作的解释。

我使用focus标志解决了第一个问题。当TabView中的当前Tab发生变化时,一个Tab获得焦点,另一个失去焦点。因此onFocusChanged()通过使用信号,您可以确切地知道一个Tab何时变为活动或非活动状态。
当整个TabView的焦点发生变化时,Tab的焦点不会改变。因此,我创建了一个Array(代码中的命名选项卡(,其中包含对每个TabView及其包含Tab的引用。有了这个,当TabView变得不活动时,我可以使用简单的for将其Tab对象中的focus设置为false

第二个问题比较棘手。我认为除了销毁和创建新FolderListModel之外,没有其他选择可以关闭showHidden标志.我们不能(或者我不能:)(为TableView动态提供model,所以我做了一个ListModel。与FolderListModel相比,常规ListModel的优点是可以清除并重新填充数据。每次folder_urlshow_hidden更改时,我都会销毁当前FolderListModel并创建一个新。创建后,我将其数据重写为ListModel


这是工作代码。

主.qml

/* main.qml */
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
ApplicationWindow {
    visible: true
    width: 1280
    height: 700
    property var tabs: [
        [tabView1, [tab1A, tab1B]],
        [tabView2, [tab2A]]
    ]
    toolBar: ToolBar {
        RowLayout {
            anchors.fill: parent
            ToolButton {
                onClicked: {    // TODO toggle folderModel.showHidden property
                    tab1A.item.show_hidden = false;
//                    tab1A.destroy();  // fixme how to refresh the view?
                }
            }
        }
    }
    Item {
        anchors.fill: parent
        SplitView {
            id: splitView
            anchors.fill: parent
            TabView {
                id: tabView1
                width: splitView.width / 2
                Tab {
                    id: tab1A
                    title: qsTr("Home")
                    source: "dirview.qml"
                    onLoaded: {
                        item.folder_url = "file:///tmp";
                    }
                    onFocusChanged: {
                        item.show_hidden = focus
                    }
                }
                onFocusChanged: {
                    if (!focus)
                        for (var i = 0 ; i < tabs[0][1].length ; i++)
                            tabs[0][1][i].focus = false
                }
                Tab {
                    id: tab1B
                    title: qsTr("Folder")
                    source: "dirview.qml"
                    onLoaded: {
                        item.folder_url = "file:///home";
                    }
                    onFocusChanged: {
                        item.show_hidden = focus
                    }
                }
            }
            TabView {
                id: tabView2
                Tab {
                    id: tab2A
                    title: qsTr("Home")
                    source: "dirview.qml"
                    onLoaded: {
                        item.folder_url = "file:///tmp";
                    }
                    onFocusChanged: {
                        item.show_hidden = focus
                    }
                }
                onFocusChanged: {
                    if (!focus)
                        for (var i = 0 ; i < tabs[1][1].length ; i++)
                            tabs[1][1][i].focus = false
                }
            }
        }
    }
}

目录视图.qml

/* dirview.qml */
import QtQuick 2.4
import QtQuick.Controls 1.4
import Qt.labs.folderlistmodel 2.1
TableView {
    property string folder_url
    property bool show_hidden
    id: tableView
    anchors.fill: parent
    TableViewColumn {
        role: "fileName"
        title: qsTr("Name")
        width: tableView.width * 0.7
    }
    TableViewColumn {
        role: "fileSize"
        title: qsTr("Size")
        width: tableView.width * 0.2
    }
    ListModel {
        id: secondListModel
    }
    property var fm
    property int folderModelCount
    onFolder_urlChanged: {
        reloadFolderModel()
    }
    onShow_hiddenChanged: {
        reloadFolderModel()
    }
    onFolderModelCountChanged: {
        resetSecondListModel()
    }
    function reloadFolderModel() {
        folderModelCount = 0
        if (typeof(fm) !== "undefined")
            fm.destroy()
        var component = Qt.createComponent("foldermodel.qml")
        if (component.status === Component.Ready)
            fm = component.createObject(
                        tableView, {"folder_url": folder_url, "show_hidden": show_hidden})
        else
            console.error(component.errorString())
        folderModelCount =
                Qt.binding(function(){return fm.folderModel.count})
    }
    function resetSecondListModel() {
        secondListModel.clear()
        for (var i = 0 ; i < folderModelCount ; i++) {
            secondListModel.append({
                                       "fileName": fm.folderModel.get(i, "fileName"),
                                       "filePath": fm.folderModel.get(i, "filePath"),
                                       "fileURL": fm.folderModel.get(i, "fileURL"),
                                       "fileBaseName": fm.folderModel.get(i, "fileBaseName"),
                                       "fileSuffix": fm.folderModel.get(i, "fileSuffix"),
                                       "fileSize": fm.folderModel.get(i, "fileSize"),
                                       "fileModified": fm.folderModel.get(i, "fileModified"),
                                       "fileAccessed": fm.folderModel.get(i, "fileAccessed"),
                                       "fileIsDir": fm.folderModel.get(i, "fileIsDir")
                                   })
        }
    }
    model: secondListModel
}

文件夹模型.qml (添加此文件(

import QtQuick 2.4
import QtQuick.Controls 1.4
import Qt.labs.folderlistmodel 2.1
Item {
    property string folder_url
    property bool show_hidden
    property alias folderModel: folderModelObject
    FolderListModel {
        id: folderModelObject
        nameFilters: ["*"]
        folder: folder_url
        showHidden: show_hidden
        showDirsFirst: true
        showDotAndDotDot: true
    }
}

现在你明白为什么QML不是很灵活了。 :)

在活动TabView(窗格(中查找当前Tab的解决方案:声明 SplitView 的属性以存储具有activeFocusTabView

添加了StatusBar来演示该功能。

import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
ApplicationWindow {
    visible: true
    width: 1280
    height: 700
    toolBar: ToolBar {
        RowLayout {
            anchors.fill: parent
            ToolButton {
                onClicked: {    // TODO toggle folderModel.showHidden property
                    // Demo: get the current tab of the active pane
                    var active_pane = splitView.activePane;
                    var cur_tab_idx = active_pane.currentIndex;
                    var cur_tab_item = active_pane.getTab(cur_tab_idx).item;
                    testLabel.text = cur_tab_item.folder_url;
                }
            }
        }
    }
    SplitView {
        id: splitView
        property TabView activePane: tabView1
        anchors.fill: parent
        TabView {
            id: tabView1
            width: splitView.width / 2
            onActiveFocusChanged: {
                if (activeFocus) {
                    splitView.activePane = tabView1;
                }
            }
            Tab {
                title: qsTr("tmp")
                source: "dirview.qml"
                onLoaded: {
                    item.folder_url = "file:///tmp";
                }
            }
            Tab {
                title: qsTr("home")
                source: "dirview.qml"
                onLoaded: {
                    item.folder_url = "file:///home";
                }
            }
        }
        TabView {
            id: tabView2
            onActiveFocusChanged: {
                if (activeFocus) {
                    splitView.activePane = tabView2;
                }
            }
            Tab {
                title: qsTr("bin")
                source: "dirview.qml"
                onLoaded: {
                    item.folder_url = "file:///bin";
                }
            }
        }
    }
    statusBar: StatusBar {
        RowLayout {
            Label {
                text: (splitView.activePane === tabView1) ? "Pane 1" : "Pane 2"
            }
            Label {
                id: testLabel
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新