我正在制作一个需要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_())
这是QT Creator的XML代码
<?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>
如果要使用QFileSystemModel,则必须使用QTreeView,但是您的.ui未实现它,因此请修改.ui。另一方面,sd.wait()
正在阻止冻结GUI,以避免必须在另一个线程中执行此任务。
考虑到上述,解决方法是:
*。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_())