2013年9月22日 星期日

PyQt4 教學2

時常安裝軟體完後,需要設定環境變數 Path,而window的設定環境感覺很麻煩,好像沒快捷鍵或指令直接呼叫,得『電腦』→右鍵『內容』→『進階電腦系統設定』→『環境變數』,才能進行設定。



所以想寫個圖形介面,來做快速設定。





第一步: 先設計介面

這是原先 window sample

所以可以很簡單的就寫出


# -*- coding: UTF8 -*-
import os, sys, win32api, win32con, _winreg
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class EditEnvironmentDlg(QDialog):
    def __init__(self, parent=None):
        super(self.__class__, self).__init__(parent)
        title =  u"編輯系統變數" 
        self.setWindowTitle(title)
        nameLabel = QLabel(u"變數名稱:")
        self.nameEdit = QLineEdit()
        valueLabel = QLabel(u"變數值:") 
        valueLabel.setAlignment(Qt.AlignRight)
        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|
                                     QDialogButtonBox.Cancel)
        grid = QGridLayout()
        grid.addWidget(nameLabel, 0, 0) 
        grid.addWidget(self.nameEdit, 0, 1) 
        grid.addWidget(valueLabel, 1, 0) 
        self.valueEdit = QLineEdit()
            
        grid.addWidget(self.valueEdit, 1, 1) 
        grid.addWidget(buttonBox, 2, 1)
        self.setLayout(grid)
        
if __name__ == "__main__":
    import sys 
    app = QApplication(sys.argv)
    dialog = EditEnvironmentDlg()
    dialog.show()
    sys.exit(app.exec_())


為了讓各個物件能整齊排列,我們用到了 QGridLayout 網狀佈局
沒用這個就得一一為各個物件設定座標,這樣是很麻煩的一件事
所以有了 grid 就變得很方便又美觀!

nameLabel(0, 0) self.nameEdit(0, 1)
valueLabel(1, 0) self.valueEdit(1, 1)
buttonBox(2, 1)


第二步 取出環境變數:

import os, sys, win32api, win32con, _winreg
 
python 有 _winreg 可以很方便幫我們操作 註冊表的查詢、修改

但我在修改時遇到 [WINDOWS Error 5] 無法存取

權限被擋了,所以不得以改用 win32api, win32con 來做操作

_winreg 語法是比較簡單,但要修改的位置有權限問題,只好
先暫時用 win32api, win32con

首先我們可以用 python IDLE 先試試是不是能查詢到我們要的



這樣就查詢到我們要到,接著我們就是把資料送到我們的程式輸入物件中

    def getEnvironmentVariable(self):
        key = win32con.HKEY_LOCAL_MACHINE
        subkey = r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
        regKey = win32api.RegOpenKey(key, subkey)
        value, datatype = win32api.RegQueryValueEx(regKey, "Path")
        self.nameEdit.setText("Path")
        self.valueEdit.setText(value)
 
 

函數 __init__ 最後添加一行

self.getEnvironmentVariable()



path裡的值通常是很長,這樣做修改對我們來講不是很方便,可以
調整一下程式讓修改值,變方便點。

原本的 self.valueEdit = QLineEdit() 換成:

self.valueEdit = QTextEdit()

並且把self.valueEdit 調大一點

self.valueEdit.setMinimumSize(320, 200)



這樣雖然方便點,但文字排版還是有亂!我們再處理一下,讓它整齊點

for line in (value.split(';')):

    if line: self.valueEdit.append(line + ';')
 
 
這樣就整齊多了,可以一目瞭然知道我們有什麼path設定

那麼最後一步就是修改了存檔了

 QLineEdit 要取得輸入框的值是用
lineEdit.text()

而 QTextEdit 的話是用 textEdit.toPlainText()

value = str(self.valueEdit.toPlainText())

#去除 QTexEdit產生的換行符 '\n'
value = value.replace('\n', '')
 
 
所以程式碼如下: 

    def setEnvironmentVariable(self):
        key = win32con.HKEY_LOCAL_MACHINE
        subkey = r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
        value = str(self.valueEdit.toPlainText())
        value = value.replace('\n', '')
        try:
            regKey = win32api.RegOpenKeyEx(key, subkey,
                                            0 ,win32con.KEY_WRITE)
            win32api.RegSetValueEx(
                    regKey, "Path", 0, 
                    win32con.REG_EXPAND_SZ, value)
        except NameError, e:
            print e
        except Exception, e:
            print e
        finally:
            win32api.RegCloseKey(regKey)
 
要讓程式按下『確認』鍵能產生動作,我們得設定一下 
 
PyQt 的 SINGAL & SLOT 訊號與插槽
 
其動作原理即 我們按下『OK』送出一個訊號 SIGNAL("accepted()")
然後這個訊號要到那邊有什麼動作呢?
 
我們希望程式幫我們修改 註冊表 
 
所以我們在程式的__init__ 初始化函數增添下面二行:
 
self.connect(buttonBox, SIGNAL("accepted()"),
                     self.setEnvironmentVariable)

按下 『Cancel』則不做修改退出
self.connect(buttonBox, SIGNAL("rejected()"),
                     self, SLOT("reject()"))

這樣整個程式就算大功告成!!

如要再進階點,做整個環境變數修改也可以



不過程式會變得較複雜,會使我解釋老半天,也沒幾個人有耐心看完!
有興趣的可以自已做研究,自已嘗試學較多進步較多!

文章還是以儘量簡單為主!

Easy To Be Happy!







沒有留言:

張貼留言