Я хочу получить рабочую QFileSystemModel в виде дерева? - PullRequest
1 голос
/ 25 сентября 2019

Я делаю программу, в которой я хочу FileTree (у меня уже есть это, но не с QfileSystemMoodel, и это усложняет дальнейшие действия).Здесь я должен иметь возможность записать немного звука с введенным именем файла (это работает) в активной папке (которую я пока не могу выбрать, так что теперь она жестко запрограммирована), а затем дерево файлов должно быть обновлено.Я предпочитаю использовать QFileSystemModel для этого, потому что это облегчает последующее редактирование.

Поэтому мой вопрос: древовидная структура с QFileSystemModel, активный / выбранный путь в качестве местоположения записи и обновление после записи или другой модификации.

Это я пробовал, но не могу заставить его работать, и мне не нужен фильтр:

import os, sys
import sounddevice as sd
from scipy.io.wavfile import write
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtWidgets import QTreeWidgetItem, QFileSystemModel
from pathlib import Path

qtcreator_file  = "mainwindow.ui" # Enter file here.
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtcreator_file)

class MyWindow(QtWidgets.QMainWindow, QtWidgets.QFileSystemModel, Ui_MainWindow):

    def __init__(self):
        QtWidgets.QMainWindow.__init__(self, parent=None)
        Ui_MainWindow.__init__(self)
        QtGui.QFileSystemModel.__init__(self, None)
        self.checks = {}
        self.FileStruckture
        self.setupUi(self)
        self.opnemen.clicked.connect(self.capture)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role != QtCore.Qt.CheckStateRole:
            return QtGui.QFileSystemModel.data(self, index, role)
        else:
            if index.column() == 0:
                return self.checkState(index)

    def flags(self, index):
        return QtGui.QFileSystemModel.flags(self, index) | QtCore.Qt.ItemIsUserCheckable

    def checkState(self, index):
        if index in self.checks:
            return self.checks[index]
        else:
            return QtCore.Qt.Checked

    def setData(self, index, value, role):
        if (role == QtCore.Qt.CheckStateRole and index.column() == 0):
            self.checks[index] = value
            self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index)
            return True 
        return QtGui.QFileSystemModel.setData(self, index, value, role)

    self.dirTreeView = QtWidgets.QTreeWidget(self.FileStruckture)
    self.dirModel = CheckableDirModel()
    self.dirTreeView.setModel(self.dirModel)

    def capture(self):

        fs = 44100  # Sample rate
        seconds = 6  # Duration of recording

        myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
        sd.wait()  # Wait until recording is finished
        locatie = "D:/DemoGIPhoofdmap/bedrijf 08"
        locatiepath = Path(locatie)
        file_name = "/" + (self.filename.text()) + ".wav"
        write_path = locatie + file_name
        write(write_path, fs, myrecording)  # Save as WAV file

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

Это работает больше всего, но не с QFileSystemMoodel и не обновляети я не могу получить из него активный путь:

import os, sys
import sounddevice as sd
from scipy.io.wavfile import write
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtWidgets import QTreeWidgetItem
from PyQt5.QtGui import QIcon
from pathlib import Path

qtcreator_file  = "mainwindow.ui" # Enter file here.
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtcreator_file)

class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        self.FileStruckture
        self.file_tree("D:/DemoGIPhoofdmap", self.FileStruckture)
        self.opnemen.clicked.connect(self.capture)


    def file_tree(self, startpath, tree):
        startpath = Path(startpath)
        for element in os.listdir(startpath):
            path_info = startpath / element
            parent_itm = QTreeWidgetItem(tree, [os.path.basename(element)])
            if os.path.isdir(path_info):
                self.file_tree(path_info, parent_itm)
                parent_itm.setIcon(0, QIcon('assets/folder.ico'))
            else:
                parent_itm.setIcon(0, QIcon('assets/file.ico'))

    def capture(self):

        fs = 44100  # Sample rate
        seconds = 6  # Duration of recording

        myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
        sd.wait()  # Wait until recording is finished
        locatie = "D:/DemoGIPhoofdmap/bedrijf 08"
        locatiepath = Path(locatie)
        file_name = "/" + (self.filename.text()) + ".wav"
        write_path = locatie + file_name
        write(write_path, fs, myrecording)  # Save as WAV file

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

Это код XML от QT Creator

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
    <x>0</x>
    <y>0</y>
    <width>827</width>
    <height>622</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="opnemen">
    <property name="geometry">
    <rect>
    <x>320</x>
    <y>60</y>
    <width>75</width>
    <height>23</height>
    </rect>
    </property>
    <property name="text">
    <string>Capture</string>
    </property>
</widget>
<widget class="QPushButton" name="importeer">
    <property name="geometry">
    <rect>
    <x>400</x>
    <y>60</y>
    <width>75</width>
    <height>23</height>
    </rect>
    </property>
    <property name="text">
    <string>Inport</string>
    </property>
</widget>
<widget class="QTreeWidget" name="FileStruckture">
    <property name="geometry">
    <rect>
    <x>10</x>
    <y>10</y>
    <width>301</width>
    <height>561</height>
    </rect>
    </property>
</widget>
<widget class="QLabel" name="label">
    <property name="geometry">
    <rect>
    <x>320</x>
    <y>10</y>
    <width>131</width>
    <height>16</height>
    </rect>
    </property>
    <property name="text">
    <string>File name for new item:</string>
    </property>
</widget>
<widget class="QLineEdit" name="filename">
    <property name="geometry">
    <rect>
    <x>320</x>
    <y>30</y>
    <width>151</width>
    <height>20</height>
    </rect>
    </property>
</widget>
<widget class="QPushButton" name="nieuwemap">
    <property name="geometry">
    <rect>
    <x>320</x>
    <y>90</y>
    <width>75</width>
    <height>23</height>
    </rect>
    </property>
    <property name="text">
    <string>New folder</string>
    </property>
</widget>
<widget class="QPushButton" name="verwijderen">
    <property name="geometry">
    <rect>
    <x>320</x>
    <y>120</y>
    <width>75</width>
    <height>23</height>
    </rect>
    </property>
    <property name="text">
    <string>Delete</string>
    </property>
</widget>
<widget class="QPushButton" name="hernoem">
    <property name="geometry">
    <rect>
    <x>400</x>
    <y>90</y>
    <width>75</width>
    <height>23</height>
    </rect>
    </property>
    <property name="text">
    <string>Rename</string>
    </property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
    <rect>
    <x>0</x>
    <y>0</y>
    <width>827</width>
    <height>21</height>
    </rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

1 Ответ

0 голосов
/ 25 сентября 2019

Если вы хотите использовать QFileSystemModel, вы должны использовать QTreeView, но ваш .ui не реализует его, поэтому измените ваш .ui.С другой стороны, sd.wait() является блокировкой, которая замораживает графический интерфейс пользователя, чтобы избежать выполнения этой задачи в другом потоке.

Учитывая вышеизложенное, решение:

*.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>615</width>
    <height>598</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
     <widget class="QTreeView" name="filestruckture"/>
    </item>
    <item>
     <layout class="QGridLayout" name="gridLayout">
      <item row="1" column="0" colspan="2">
       <widget class="QLineEdit" name="filename"/>
      </item>
      <item row="3" column="0">
       <widget class="QPushButton" name="nieuwemap">
        <property name="text">
         <string>New folder</string>
        </property>
       </widget>
      </item>
      <item row="4" column="0">
       <widget class="QPushButton" name="verwijderen">
        <property name="text">
         <string>Delete</string>
        </property>
       </widget>
      </item>
      <item row="2" column="1">
       <widget class="QPushButton" name="importeer">
        <property name="text">
         <string>Inport</string>
        </property>
       </widget>
      </item>
      <item row="0" column="0" colspan="2">
       <widget class="QLabel" name="label">
        <property name="text">
         <string>File name for new item:</string>
        </property>
       </widget>
      </item>
      <item row="3" column="1">
       <widget class="QPushButton" name="hernoem">
        <property name="text">
         <string>Rename</string>
        </property>
       </widget>
      </item>
      <item row="2" column="0">
       <widget class="QPushButton" name="opnemen">
        <property name="text">
         <string>Capture</string>
        </property>
       </widget>
      </item>
      <item row="5" column="0">
       <spacer name="verticalSpacer">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>40</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>615</width>
     <height>30</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

*. py

import os
import sys
from pathlib import Path

from functools import partial

import sounddevice as sd
from scipy.io.wavfile import write

from PyQt5 import QtCore, QtGui, QtWidgets, uic

qtcreator_file = "mainwindow.ui"  # Enter file here.
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtcreator_file)


class CaptureWorker(QtCore.QObject):
    started = QtCore.pyqtSignal()
    finished = QtCore.pyqtSignal()

    @QtCore.pyqtSlot(str)
    def save_to(self, path):
        self.started.emit()
        fs = 44100  # Sample rate
        seconds = 6  # Duration of recording
        myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
        sd.wait()
        write(path, fs, myrecording)
        self.finished.emit()


class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.setupUi(self)

        self.root_path = "D:/DemoGIPhoofdmap/bedrijf 08"

        model = QtWidgets.QFileSystemModel(self)
        self.filestruckture.setModel(model)
        model.setRootPath(self.root_path)
        self.filestruckture.setRootIndex(model.index(model.rootPath()))

        thread = QtCore.QThread(self)
        thread.start()

        self.capture_worker = CaptureWorker()
        self.capture_worker.moveToThread(thread)

        self.capture_worker.started.connect(partial(self.opnemen.setEnabled, False))
        self.capture_worker.finished.connect(partial(self.opnemen.setEnabled, True))

        self.opnemen.clicked.connect(self.capture)

    def capture(self):
        name = self.filename.text()
        if name:
            locatie = self.root_path
            locatiepath = Path(locatie)
            file_name = os.path.join(locatiepath, name + ".wav")
            wrapper = partial(self.capture_worker.save_to, file_name)
            QtCore.QTimer.singleShot(0, wrapper)
        else:
            print("set the filename")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())
...