-
-
Save hongwen000/497ca355641542f82c96d861e16152dd to your computer and use it in GitHub Desktop.
PyQt配置备份程序
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PyQt6.QtCore import QAbstractListModel, Qt, QModelIndex, pyqtSlot | |
from PyQt6.QtGui import QGuiApplication | |
from PyQt6.QtQml import QQmlApplicationEngine | |
import os | |
import shutil | |
from typing import Optional | |
import shutil | |
import os | |
import time | |
class ConfigModel: | |
def __init__(self, name: str, base_dir: str, files: list[str]): | |
self.name = name | |
self.dir_base = base_dir | |
self.files = files | |
class ConfigBackupWorker(): | |
def __init__(self, model: ConfigModel, base_dir: str) -> None: | |
self.model = model | |
self.base_dir = base_dir | |
def backupConfig(self) -> None: | |
# create base backup dir if not exists | |
backup_dir = os.path.join(self.base_dir, self.model.name + "_backup") | |
os.makedirs(backup_dir, exist_ok=True) | |
for file in self.model.files: | |
soruce = os.path.join(self.model.dir_base, file) | |
soruce = os.path.expanduser(path=soruce) | |
target = os.path.join(backup_dir, file) | |
if not os.path.exists(soruce): | |
continue | |
# 创建target_file的父目录 | |
target_parent_dir = os.path.dirname(target) | |
os.makedirs(target_parent_dir, exist_ok=True) | |
if os.path.isdir(soruce): | |
shutil.copytree(soruce, target) | |
else: | |
shutil.copy2(soruce, target) | |
def restoreConfig(self) -> None: | |
backup_dir = os.path.join(self.base_dir, self.model.name + "_backup") | |
for file in self.model.files: | |
rsource = os.path.join(backup_dir, file) | |
rtarget = os.path.join(self.model.dir_base, file) | |
rtarget = os.path.expanduser(path=rtarget) | |
# 创建被还原文件的父目录 | |
os.makedirs(os.path.dirname(rtarget), exist_ok=True) | |
# 备份旧文件 | |
tsp = time.strftime("%Y_%m_%d", time.localtime(time.time())) | |
if os.path.exists(rtarget): | |
rbackup = rtarget + "_old_" + tsp | |
os.rename(rtarget, rbackup) | |
if os.path.isdir(rsource): | |
shutil.copytree(rsource, rtarget) | |
else: | |
shutil.copy2(rsource, rtarget) | |
class ConfigModelList(QAbstractListModel): | |
def __init__(self, configs: Optional[list[ConfigModel]] = None, parent: Optional[QAbstractListModel] =None): | |
super().__init__(parent) | |
self.configs = configs or [] | |
def rowCount(self, parent=QModelIndex()): | |
return len(self.configs) | |
def data(self, index, role=Qt.ItemDataRole.DisplayRole): | |
if not index.isValid() or not 0 <= index.row() < self.rowCount(): | |
return None | |
config = self.configs[index.row()] | |
if role == Qt.ItemDataRole.DisplayRole: | |
return config.name | |
return None | |
def roleNames(self): | |
return {Qt.ItemDataRole.DisplayRole: b"name"} | |
@pyqtSlot(int) | |
def backupConfig(self, row_index: int): | |
if row_index >= self.rowCount(): | |
return | |
config = self.configs[row_index] | |
worker = ConfigBackupWorker(config, os.path.join(os.getcwd(), "backup")) | |
worker.backupConfig() | |
@pyqtSlot(int) | |
def restoreConfig(self, row_index: int): | |
if row_index >= self.rowCount(): | |
return | |
config = self.configs[row_index] | |
worker = ConfigBackupWorker(config, os.path.join(os.getcwd(), "backup")) | |
worker.restoreConfig() | |
import yaml | |
import sys | |
if __name__ == '__main__': | |
app = QGuiApplication(sys.argv) | |
engine = QQmlApplicationEngine() | |
# Read config from backup_restore.yaml | |
configs = [] | |
with open("backup_restore.yaml", 'r') as file: | |
data = yaml.safe_load(file) | |
for item in data['configures']: | |
name = item['name'] | |
base_dir = item['base_dir'] | |
files = item['files'] | |
for f in files: | |
full_path = os.path.join(base_dir, f) | |
abs_path = os.path.expanduser(full_path) | |
model = ConfigModel(name, base_dir, files) | |
configs.append(model) | |
configmodelList = ConfigModelList() | |
configmodelList.configs = configs | |
engine.rootContext().setContextProperty("configModelList", configmodelList) | |
engine.quit.connect(app.quit) | |
engine.load("configbackup.qml") | |
sys.exit(app.exec()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
configures: | |
- | |
name: neovim | |
base_dir: ~\AppData\Local\nvim\ | |
files: | |
- init.vim | |
- | |
name: ideavim | |
base_dir: ~\ | |
files: | |
- .ideavimrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import QtQuick 2.15 | |
import QtQuick.Controls 2.15 | |
ApplicationWindow { | |
width: 500 | |
height: 500 | |
title: "Config Backup" | |
visible: true | |
id: root | |
Column { | |
width: parent.width | |
height: parent.height | |
spacing: 10 | |
ListView { | |
id: configListView | |
width: parent.width | |
height: parent.height - 100 | |
model: configModelList | |
spacing: 10 | |
delegate: Rectangle { | |
width: parent.width | |
height: 50 | |
color: ListView.isCurrentItem?"gray":"white" | |
Text { | |
text: name | |
} | |
MouseArea { | |
anchors.fill: parent | |
onClicked: configListView.currentIndex = index //实现item切换 | |
} | |
} | |
Component.onCompleted: { | |
console.info(configModelList); | |
} | |
} | |
Row { | |
spacing: 10 | |
width: parent.width | |
height: 50 | |
Button { | |
text: "Backup" | |
onClicked: { | |
console.debug(configListView.currentIndex); | |
configModelList.backupConfig(configListView.currentIndex) | |
} | |
} | |
Button { | |
text: "Restore" | |
onClicked: { | |
configModelList.restoreConfig(configListView.currentIndex) | |
} | |
} | |
} | |
} | |
Component { | |
id: scheduleItem | |
Rectangle { | |
width: parent.width | |
height: 50 | |
color: "red" | |
Text { | |
text: "test" | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment