pyqt5學(xué)習(xí)筆記

軟硬件環(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前綴的揪阿。


設(shè)計(jì)的簡(jiǎn)易界面

為了便于編碼我們可以在對(duì)象查看器里對(duì)控件進(jìn)行重命名。

對(duì)象查看器

一個(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)換,如下圖:

pyuic

沒(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)諒哈。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柜候,一起剝皮案震驚了整個(gè)濱河市搞动,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渣刷,老刑警劉巖鹦肿,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異辅柴,居然都是意外死亡箩溃,警方通過(guò)查閱死者的電腦和手機(jī)瞭吃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涣旨,“玉大人歪架,你說(shuō)我怎么就攤上這事∨福” “怎么了和蚪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)烹棉。 經(jīng)常有香客問(wèn)我惠呼,道長(zhǎng),這世上最難降的妖魔是什么峦耘? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任剔蹋,我火速辦了婚禮,結(jié)果婚禮上辅髓,老公的妹妹穿的比我還像新娘泣崩。我一直安慰自己,他們只是感情好洛口,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布矫付。 她就那樣靜靜地躺著,像睡著了一般第焰。 火紅的嫁衣襯著肌膚如雪买优。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天挺举,我揣著相機(jī)與錄音杀赢,去河邊找鬼。 笑死湘纵,一個(gè)胖子當(dāng)著我的面吹牛脂崔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梧喷,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼砌左,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了铺敌?” 一聲冷哼從身側(cè)響起汇歹,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎偿凭,沒(méi)想到半個(gè)月后产弹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笔喉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年取视,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了硝皂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片常挚。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡作谭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奄毡,到底是詐尸還是另有隱情折欠,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布吼过,位于F島的核電站锐秦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏盗忱。R本人自食惡果不足惜酱床,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望趟佃。 院中可真熱鬧扇谣,春花似錦、人聲如沸闲昭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)序矩。三九已至鸯绿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間簸淀,已是汗流浹背瓶蝴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留租幕,地道東北人囊蓝。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像令蛉,于是被迫代替她去往敵國(guó)和親聚霜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容