軟硬件環(huán)境
- OS X EI Capitan
- Python 3.5.1
- PyQt 5.5.1
- PyCharm 5.0.4
前言
Qt是一個(gè)開(kāi)源的跨平臺(tái)的GUI框架,為很多計(jì)算機(jī)語(yǔ)言提供了應(yīng)用程序開(kāi)發(fā)接口旁壮,另外還提供了集成開(kāi)發(fā)環(huán)境QtCreator哥牍、UI制作工作QtDesigner,使用起來(lái)既簡(jiǎn)單方便环鲤,又可以提升開(kāi)發(fā)的速度纯趋。
安裝開(kāi)發(fā)環(huán)境 - Python 3.5.1
下載地址 https://www.python.org/downloads/mac-osx - Sip 4.17
下載地址 https://www.riverbankcomputing.com/software/sip/download - PyQt 5.5.1
下載地址 https://riverbankcomputing.com/software/pyqt/download5 - qt 5.5.1
下載地址 http://www.qt.io/download/
ide推薦使用PyCharm。
需要注意的是: - mac 平臺(tái)Designer的路徑
/Users/yourname/Qt5.5.1/5.5/clang_64/bin/Designer.app - mac 自帶的python2.* 不建議刪除python可以多版本并存的冷离,使用python3 的時(shí)候加上版本號(hào)就好了吵冒。
python3 -v
- pyqt5版本要和qt的版本相同不然使用pyuic5 時(shí)候會(huì)出錯(cuò)。
因?yàn)楣ぷ餍枰谱髁艘粋€(gè)根據(jù)模版音頻文件夾整理另外一個(gè)有相同編號(hào)的雜亂音頻文件夾的小工具西剥。
一 界面設(shè)計(jì)
打開(kāi)Qt Designer 選擇 Main Window 顧名思義就是主窗口痹栖。
在窗體部件盒子選擇我們需要的控件拖拽到主窗體,下圖使用了Lable、lineEdit瞭空、pushButton,在qt中所有的控件都是加了Q前綴的揪阿。
為了便于編碼我們可以在對(duì)象查看器里對(duì)控件進(jìn)行重命名。
一個(gè)簡(jiǎn)易的界面設(shè)計(jì)好了,我們將它保存為ui.ui文件咆畏,這里要注意一下南捂,Qt Designer設(shè)計(jì)出來(lái)的文件默認(rèn)為ui文件,里面包含的類(lèi)css布局設(shè)計(jì)語(yǔ)言旧找,我們還需要將它轉(zhuǎn)換為.py文件黑毅。
如果使用的PyCharm,可以在Tools->External Tools->Pyuic 轉(zhuǎn)換,如下圖:
沒(méi)有使用PyCharm的伙伴可以通過(guò)終端轉(zhuǎn)換:
pyuic5 -o ui.py ui.ui
生成的代碼如下
rom PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(504, 293)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(40, 40, 284, 123))
self.widget.setObjectName("widget")
self.gridLayout = QtWidgets.QGridLayout(self.widget)
self.gridLayout.setObjectName("gridLayout")
self.label_model = QtWidgets.QLabel(self.widget)
self.label_model.setObjectName("label_model")
self.gridLayout.addWidget(self.label_model, 0, 0, 1, 1)
self.lineEdit_model = QtWidgets.QLineEdit(self.widget)
self.lineEdit_model.setObjectName("lineEdit_model")
self.gridLayout.addWidget(self.lineEdit_model, 0, 1, 1, 1)
self.pushButton_begin = QtWidgets.QPushButton(self.widget)
self.pushButton_begin.setObjectName("pushButton_begin")
self.gridLayout.addWidget(self.pushButton_begin, 0, 2, 1, 1)
self.label_res = QtWidgets.QLabel(self.widget)
self.label_res.setObjectName("label_res")
self.gridLayout.addWidget(self.label_res, 1, 0, 1, 1)
self.lineEdit_res = QtWidgets.QLineEdit(self.widget)
self.lineEdit_res.setObjectName("lineEdit_res")
self.gridLayout.addWidget(self.lineEdit_res, 1, 1, 1, 1)
self.label_out = QtWidgets.QLabel(self.widget)
self.label_out.setObjectName("label_out")
self.gridLayout.addWidget(self.label_out, 2, 0, 1, 1)
self.lineEdit_out = QtWidgets.QLineEdit(self.widget)
self.lineEdit_out.setObjectName("lineEdit_out")
self.gridLayout.addWidget(self.lineEdit_out, 2, 1, 1, 1)
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 3, 0, 1, 1)
self.lineEdit_regex = QtWidgets.QLineEdit(self.widget)
self.lineEdit_regex.setObjectName("lineEdit_regex")
self.gridLayout.addWidget(self.lineEdit_regex, 3, 1, 1, 1)
self.label_model.raise_()
self.pushButton_begin.raise_()
self.lineEdit_model.raise_()
self.label_res.raise_()
self.lineEdit_res.raise_()
self.label_out.raise_()
self.lineEdit_out.raise_()
self.lineEdit_regex.raise_()
self.label.raise_()
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 504, 22))
self.menubar.setObjectName("menubar")
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
MainWindow.setMenuBar(self.menubar)
self.menubar.addAction(self.menu.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label_model.setText(_translate("MainWindow", "模版路徑:"))
self.pushButton_begin.setText(_translate("MainWindow", "開(kāi)始"))
self.label_res.setText(_translate("MainWindow", "資源路徑:"))
self.label_out.setText(_translate("MainWindow", "輸出路徑:"))
self.label.setText(_translate("MainWindow", "正則表達(dá)式:"))
self.menu.setTitle(_translate("MainWindow", "菜單"))
為了代碼與界面分離钦讳,我們可以新建一個(gè)文件qui.py導(dǎo)入ui.py:
from ui import Ui_MainWindow
from PyQt5.QtWidgets import QApplication , QMainWindow
class Mainwindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(Mainwindow, self).__init__()
self.setupUi(self)
二 業(yè)務(wù)邏輯
核心業(yè)務(wù)重要是對(duì)文件夾下的所有文件進(jìn)行遍歷:
# 獲取指定路徑下所有指定后綴的文件
# dir 指定路徑
# ext 指定后綴矿瘦,鏈表&不需要帶點(diǎn) 或者不指定。例子:['xml', 'java']
def GetFileFromThisRootDir(self, dir, ext = None):
allfiles = []
needExtFilter = (ext != None)
for root,dirs,files in os.walk(dir):
for filespath in files:
filepath = os.path.join(root, filespath)
extension = os.path.splitext(filepath)[1][1:]
if needExtFilter and extension == ext in ext:
allfiles.append(filepath)
return allfiles
shutil模塊提供了復(fù)制文件的方法,re 模塊提供了正則表達(dá)式功能愿卒,我們需要導(dǎo)入缚去,完整工具類(lèi)代碼如下:
import os
import re
import shutil
class Ltool(object):
def __init__(self):
pass
# 獲取指定路徑下所有指定后綴的文件
# dir 指定路徑
# ext 指定后綴,鏈表&不需要帶點(diǎn) 或者不指定琼开。例子:['xml', 'java']
def GetFileFromThisRootDir(self, dir, ext = None):
allfiles = []
needExtFilter = (ext != None)
for root,dirs,files in os.walk(dir):
for filespath in files:
filepath = os.path.join(root, filespath)
extension = os.path.splitext(filepath)[1][1:]
if needExtFilter and extension == ext in ext:
allfiles.append(filepath)
return allfiles
# 獲取指定路徑下所有的文件夾
# dir 指定路徑
def GetDirFromThisRootDir(self, dir):
alldirs = []
for root,dirs,files in os.walk(dir):
alldirs.append(root)
return alldirs
# 復(fù)制目錄
# dstDir 目標(biāo)路徑
# srcDir 源路徑
def CopyDirBySrcDirPathToDstDir(self, dstDir, srcDir):
allDirs = self.GetDirFromThisRootDir(srcDir)
for d in allDirs:
newdir = d.replace(srcDir, dstDir)
if os.path.exists(newdir):
pass
else:
os.mkdir(newdir)
# 復(fù)制文件到目標(biāo)位置
def CopyFilesByModelDir(self, modelDir, dstDir, srcDir, regex = r'([0-9]{5})', ext = 'mp3'):
errorFiles = []
allFiles = self.GetFileFromThisRootDir(srcDir, ext)
modelFiles = self.GetFileFromThisRootDir(modelDir, ext)
self.CopyDirBySrcDirPathToDstDir(dstDir, modelDir)
#復(fù)制符合規(guī)則的文件
for f in allFiles:
m = re.findall(regex,f)
if len(m) == 1:
for demofile in modelFiles:
z = re.findall(regex, demofile)
if m == z:
newfile = demofile.replace(modelDir, dstDir)
shutil.copy(f, newfile)
else:
errorFiles.append(f)
for f in errorFiles:
logging.debug("errorfile", f)
現(xiàn)在可以回過(guò)頭完善下qui.py:
from ui import Ui_MainWindow
from PyQt5.QtWidgets import QApplication , QMainWindow
from Ltool import Ltool
class Mainwindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(Mainwindow, self).__init__()
self.setupUi(self)
self.ltool = Ltool()
self.pushButton_begin.clicked.connect(self.beginCopyfun)
def beginCopyfun(self):
modelDir = self.lineEdit_model.text()
dstDir = self.lineEdit_out.text()
srcDir = self.lineEdit_res.text()
regex = self.lineEdit_regex.text()
self.ltool.CopyFilesByModelDir(modelDir, dstDir, srcDir)
main.py
# -*- coding: utf-8 -*-
import sys
import common
import logging
from qui import *
def initLogConfiguration():
'''
初始化日志配置
'''
logging.basicConfig(level = logging.DEBUG,
filename = common.LOGFILE,
filemode = 'a+',
format = '%(asctime)s - %(filename)s - line %(lineno)-4d - %(levelname)s - %(message)s',
datefmt = '%m-%d %H:%M')
if __name__ == '__main__':
'''
主函數(shù)
'''
initLogConfiguration()
app = QApplication(sys.argv)
mainWindow = Mainwindow()
mainWindow.show()
sys.exit(app.exec_())
新人學(xué)習(xí)中易结,請(qǐng)見(jiàn)諒哈。