Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python QTreeView/QFileSystemModel-比较文件和;显色_Python_Pyside_Pyside2 - Fatal编程技术网

Python QTreeView/QFileSystemModel-比较文件和;显色

Python QTreeView/QFileSystemModel-比较文件和;显色,python,pyside,pyside2,Python,Pyside,Pyside2,我有两个QFileSystemModel附加的QTreeview。一个是本地目录,另一个指向服务器 我期待着改变文件上的文本颜色的基础上,其关系到相反的位置。例如: 如果服务器和本地都有相同的修改时间-设置为绿色 如果服务器是最新的-将本地设置为红色,服务器设置为橙色。等等 我有过多个这样的工作示例,但我总是遇到同样的障碍,用户界面反应迟钝。我在两个QFileSystemModels中都使用了data()函数来实现这一点,我尝试在data()之外执行线程操作以返回颜色,但这只会使我的所有文件都变

我有两个QFileSystemModel附加的QTreeview。一个是本地目录,另一个指向服务器

我期待着改变文件上的文本颜色的基础上,其关系到相反的位置。例如: 如果服务器和本地都有相同的修改时间-设置为绿色 如果服务器是最新的-将本地设置为红色,服务器设置为橙色。等等

我有过多个这样的工作示例,但我总是遇到同样的障碍,用户界面反应迟钝。我在两个QFileSystemModels中都使用了data()函数来实现这一点,我尝试在data()之外执行线程操作以返回颜色,但这只会使我的所有文件都变成灯光显示。基于我移动鼠标,文件将随机变为绿色/红色/橙色

我目前有一个date modified列作为一个解决方案,但它不能帮助用户知道他们是否已经从本地服务器获得了一个文件

有没有人能在没有UI chug的情况下完成类似的工作?或者甚至找到一个方法从线程返回结果,并让它为正确的条目工作

我理解这可能看起来有点混乱,但这里是我初始化根的地方(其中一些全局变量在其他地方使用)

def initroot(self,loc):
'''
此函数用于设置服务器和本地服务器的起始目录
不处理除顶层以外的任何事情
'''
全局本地掩码
全局服务器掩码
全局服务器根
全局用户根
全局gserver模型
全局GlocalModel
如果loc==“服务器”:
self.serverRoot=self.cb\u serverWorkspace.currentText()
serverRoot=self.serverRoot
self.serverModel=ServerFileSystemModel()
GserverModel=self.serverModel
self.tv_serverFiles.setModel(self.serverModel)
#self.serverModel.setRootPath(QtCore.QDir.rootPath())
self.serverModel.setRootPath(“”)
self.tv_serverFiles.setRootIndex(self.serverModel.index(self.serverRoot))
self.tv_serverFiles.setUniformRowHeights(True)
self.tv_serverFiles.setExpandsOnDoubleClick(True)
self.tv\u serverFiles.hideColumn(1)
self.tv\u serverFiles.hideColumn(2)
self.tv_serverFiles.setColumnWidth(0400)
如果loc==“本地”:
self.userRoot=self.cb\u localWorkspace.currentText()
userRoot=self.userRoot
self.localModel=LocalFileSystemModel()
GlocalModel=self.localModel
self.tv\u localFiles.setModel(self.localModel)
#self.localModel.setRootPath(QtCore.QDir.rootPath())
self.localModel.setRootPath(“”)
self.tv_localFiles.setRootIndex(self.localModel.index(self.userRoot))
self.tv_serverFiles.setUniformRowHeights(True)
self.tv\u localFiles.setExpandsOnDoubleClick(True)
self.tv\u localFiles.hideColumn(1)
self.tv\u localFiles.hideColumn(2)
self.tv_localFiles.setColumnWidth(0400)
然后,我的两个QFileSystemModels几乎就是这样(这是我的非线程示例)

类服务器文件系统模型(qtwidts.QFileSystemModel):
定义初始化(self,*args,**kwargs):
super(ServerFileSystemModel,self)。\uuuu init\uuuu(*args,**kwargs)
def数据(self,index,role=QtCore.Qt.DisplayRole):
尝试:
全局GlocalModel
全局gserver模型
serverPath=self.filePath(索引)
localMask=userRoot+“/”
serverMask=serverRoot+“/”
newPath=serverPath.replace(serverMask,localMask)
serverIndex=GserverModel.index(serverPath)
localIndex=GlocalModel.index(新路径)
如果role==QtCore.Qt.TextColorRole和serverPath.endswith(“.fbx”)以及os.path.exists(newPath)存在,并且下载==False:
如果GlocalModel.lastModified(localIndex)=GserverModel.lastModified(serverIndex):
返回QtGui.QColor(#58cd1c)
如果GlocalModel.lastModified(localIndex)GserverModel.lastModified(serverIndex):
返回QtGui.QColor(#ed1111)
返回super(ServerFileSystemModel,self).data(索引,角色)
除:
返回super(ServerFileSystemModel,self).data(索引,角色)
还有什么事就告诉我

编辑******

我被要求放置最小的可复制代码,所以我们开始吧

主窗口

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

        self.userRoot = "D:/OCooke_Workspace"
        self.serverRoot = "D:/OCooke_Server"
        
        self.initRoots("Local")
        self.initRoots("Server")

    
    def initRoots(self, loc):
        '''
        This function sets the starting directories for both server and local
        Does not handle anything except top level
        '''
                
        if loc == "Server":
            self.serverModel = ServerFileSystemModel()
            self.tv_serverFiles.setModel(self.serverModel)
            #self.serverModel.setRootPath(QtCore.QDir.rootPath())
            self.serverModel.setRootPath("")
         self.tv_serverFiles.setRootIndex(self.serverModel.index(self.serverRoot))
            self.tv_serverFiles.setUniformRowHeights(True)
            self.tv_serverFiles.setExpandsOnDoubleClick(True)
            self.tv_serverFiles.hideColumn(1)
            self.tv_serverFiles.hideColumn(2)
            self.tv_serverFiles.setColumnWidth(0,400)

        if loc == "Local":
            self.localModel = LocalFileSystemModel()
            self.tv_localFiles.setModel(self.localModel)
            #self.localModel.setRootPath(QtCore.QDir.rootPath())
            self.localModel.setRootPath("")
            self.tv_localFiles.setRootIndex(self.localModel.index(self.userRoot))
            self.tv_serverFiles.setUniformRowHeights(True)
            self.tv_localFiles.setExpandsOnDoubleClick(True)
            self.tv_localFiles.hideColumn(1)
            self.tv_localFiles.hideColumn(2)
            self.tv_localFiles.setColumnWidth(0,400)
q无法与信号一起命名

class WorkerSignals(QObject):

    finished = Signal()
    result = Signal(object)
    progress = Signal(int)


            
            
class ColourWorker(QRunnable):
    '''
    Worker thread

    Inherits from QRunnable to handler worker thread setup, signals and wrap-up.

    :param callback: The function callback to run on this worker thread. Supplied args and
                     kwargs will be passed through to the runner.
    :type callback: function
    :param args: Arguments to pass to the callback function
    :param kwargs: Keywords to pass to the callback function

    '''

    def __init__(self, fn, *args, **kwargs):
        super(ColourWorker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        self.signals = WorkerSignals()

        # Add the callback to our kwargs
        self.kwargs['progress_callback'] = self.signals.progress
        self.kwargs['indexy']
        
        
        
    @Slot()
    def run(self):
        '''
        Initialise the runner function with passed args, kwargs.
        '''

        # Retrieve args/kwargs here; and fire processing using them
        try:
            result = self.fn(*self.args, **self.kwargs)
        except:
            traceback.print_exc()
            exctype, value = sys.exc_info()[:2]
            self.signals.error.emit((exctype, value, traceback.format_exc()))
        else:
            self.signals.result.emit(result)  # Return the result of the processing
        finally:
            self.signals.finished.emit()  # Done
class ServerFileSystemModel(QFileSystemModel):
    def __init__(self, *args, **kwargs):
        super(ServerFileSystemModel, self).__init__(*args, **kwargs)

        self.threadpool = QThreadPool()
        self.colour = None

    def data(self, index, role=Qt.DisplayRole):

        if role == Qt.TextColorRole:
            worker = ColourWorker(self.execute_this_fn, indexy = index) # Any other args, kwargs are passed to the run function
            worker.signals.result.connect(self.print_output)
            worker.signals.finished.connect(self.thread_complete)
            # Execute
            self.threadpool.start(worker)


            return self.colour
        return super(ServerFileSystemModel, self).data(index, role)
        
#  

 
    def execute_this_fn(self, progress_callback, indexy):

        serverPath = self.filePath(indexy)
              
        localMask = "D:/OCooke_Workspace/"
        serverMask = "D:/OCooke_Server/"
              
        #create an expected path to the local using the server address
        # D:/OCooke_Server/2020/file1 turns into  D:/OCooke_Workspace/2020/file1
        newPath = serverPath.replace(serverMask, localMask)

        #Check the stat time between the two locations
        if os.stat(newPath).st_mtime == os.stat(serverPath).st_mtime:
            return QColor("#58cd1c")
        if os.stat(newPath).st_mtime < os.stat(serverPath).st_mtime:
            return QColor("#ed7011")
        if os.stat(newPath).st_mtime > os.stat(serverPath).st_mtime:
            return QColor("#ed1111")

        else:
            return None
        
 
    def print_output(self, s):
        #return the value of color
        self.colour = s
        
 
    def thread_complete(self):
        #ive tried passing the color once the thread completes, no joy
        pass



    
    
class LocalFileSystemModel(QFileSystemModel):
    def __init__(self, *args, **kwargs):
        super(LocalFileSystemModel, self).__init__(*args, **kwargs)

    def data(self, index, role=Qt.DisplayRole):


        return super(LocalFileSystemModel, self).data(index, role)
最后是两个QSystemFileModels

class WorkerSignals(QObject):

    finished = Signal()
    result = Signal(object)
    progress = Signal(int)


            
            
class ColourWorker(QRunnable):
    '''
    Worker thread

    Inherits from QRunnable to handler worker thread setup, signals and wrap-up.

    :param callback: The function callback to run on this worker thread. Supplied args and
                     kwargs will be passed through to the runner.
    :type callback: function
    :param args: Arguments to pass to the callback function
    :param kwargs: Keywords to pass to the callback function

    '''

    def __init__(self, fn, *args, **kwargs):
        super(ColourWorker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        self.signals = WorkerSignals()

        # Add the callback to our kwargs
        self.kwargs['progress_callback'] = self.signals.progress
        self.kwargs['indexy']
        
        
        
    @Slot()
    def run(self):
        '''
        Initialise the runner function with passed args, kwargs.
        '''

        # Retrieve args/kwargs here; and fire processing using them
        try:
            result = self.fn(*self.args, **self.kwargs)
        except:
            traceback.print_exc()
            exctype, value = sys.exc_info()[:2]
            self.signals.error.emit((exctype, value, traceback.format_exc()))
        else:
            self.signals.result.emit(result)  # Return the result of the processing
        finally:
            self.signals.finished.emit()  # Done
class ServerFileSystemModel(QFileSystemModel):
    def __init__(self, *args, **kwargs):
        super(ServerFileSystemModel, self).__init__(*args, **kwargs)

        self.threadpool = QThreadPool()
        self.colour = None

    def data(self, index, role=Qt.DisplayRole):

        if role == Qt.TextColorRole:
            worker = ColourWorker(self.execute_this_fn, indexy = index) # Any other args, kwargs are passed to the run function
            worker.signals.result.connect(self.print_output)
            worker.signals.finished.connect(self.thread_complete)
            # Execute
            self.threadpool.start(worker)


            return self.colour
        return super(ServerFileSystemModel, self).data(index, role)
        
#  

 
    def execute_this_fn(self, progress_callback, indexy):

        serverPath = self.filePath(indexy)
              
        localMask = "D:/OCooke_Workspace/"
        serverMask = "D:/OCooke_Server/"
              
        #create an expected path to the local using the server address
        # D:/OCooke_Server/2020/file1 turns into  D:/OCooke_Workspace/2020/file1
        newPath = serverPath.replace(serverMask, localMask)

        #Check the stat time between the two locations
        if os.stat(newPath).st_mtime == os.stat(serverPath).st_mtime:
            return QColor("#58cd1c")
        if os.stat(newPath).st_mtime < os.stat(serverPath).st_mtime:
            return QColor("#ed7011")
        if os.stat(newPath).st_mtime > os.stat(serverPath).st_mtime:
            return QColor("#ed1111")

        else:
            return None
        
 
    def print_output(self, s):
        #return the value of color
        self.colour = s
        
 
    def thread_complete(self):
        #ive tried passing the color once the thread completes, no joy
        pass



    
    
class LocalFileSystemModel(QFileSystemModel):
    def __init__(self, *args, **kwargs):
        super(LocalFileSystemModel, self).__init__(*args, **kwargs)

    def data(self, index, role=Qt.DisplayRole):


        return super(LocalFileSystemModel, self).data(index, role)

请提供一个示例并改进缩进您的示例远不是最小的,也不是可复制的,但这不是主要问题:模型的
data()
函数应该立即返回,这意味着不应该有阻塞(或线程相关)函数,这是因为项目视图可能会调用
data()
每秒数百或数千次,即使是将鼠标悬停在项目上,甚至是相同的项目。坦白地说,我认为您的系统对于您的需求来说太复杂了,我建议您重新考虑整个概念,因为您正在使用(可能)相同结构的固定路径。