从TabView获取活动标签并更改项属性

时间:2015-11-06 00:16:28

标签: qt qml qt5 qtquick2

在双窗格文件管理器的context中,我并排有两个TabView个项目,每个项目当然包含多个标签,每个Tab加载{{1}使用TableView显示特定目录的内容。

FolderListModel

我当前的任务是实现一个工具栏按钮,以切换活动标签中显示的SplitView TabView Tab Tab TabView Tab 实例的showHidden属性。因此,我需要一种方法来找出当前活动的标签是什么。

接下来,一旦我获得了有效FolderListModel,我需要更改Tab,特别是感兴趣的属性为Tab.item.some_property,这是{{1}的别名底层show_hidden的属性。例如,硬编码的场景是:

showHidden

首先我需要根据它是否处于活动状态来获取FolderListModel,其次,在我更改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

true

2 个答案:

答案 0 :(得分:0)

以下是我如何让它发挥作用的解释。

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

第二个问题更棘手。我认为没有其他方法可以关闭showHidden旗帜而不是销毁和创建新的FolderListModel。我们不能(或我不能:)动态地向model提供TableView,所以我创建了ListModel。与ListModel相比,常规FolderListModel的优势在于可以清除并重新填充数据。每次folder_urlshow_hidden更改时,我都会销毁当前FolderListModel并创建一个新的ListModel。创建后,我将其数据重写为/* 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 } } } } }

这是工作代码。

main.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
}

dirview.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
    }
}

foldermodel.qml (添加此文件)

from contextlib import contextmanager

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

@contextmanager
def db_session(db_url):
    """ Creates a context with an open SQLAlchemy session.
    """
    engine = create_engine(db_url, convert_unicode=True)
    connection = engine.connect()
    db_session = scoped_session(sessionmaker(autocommit=False, autoflush=True, bind=engine))
    yield db_session
    db_session.close()
    connection.close()

现在您了解为什么QML不够灵活。 :)

答案 1 :(得分:0)

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

添加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
            }
        }
    }
}
相关问题