python - 我想在树视图中使用 QFileSystemModel 吗?
问题描述
我正在制作一个我想要一个 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_())
这最有效,但它不适用于 QFileSystemMoodle 并且它不会更新,我无法从中获取活动路径:
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_())
推荐阅读
- c# - 使用多个表单在列表框中编辑数据的问题
- c# - 将文件读取到字节在项目中无法正常工作
- javascript - 如何在 Vue Js 中进行选择性悬停?
- javascript - 保护用户定义的 javascript 函数以保护 node.js 服务器
- r - 如何只保留R中单列中的数字
- css - 自动完成时浮动标签的不良行为
- mysql - 如何在 Mysql 中修复此错误。“错误 1452 (23000):无法添加或更新子行:外键约束失败。”
- r - 在 for 循环内的向量中获取向量的名称
- python-3.x - 如何在while循环中自动更改变量值?
- java - 我无法将 3d 对象绑定到另一个对象的中心