使用 PyQT5 为 gma(以栅格重采样为例)构造一个 GUI 界面

GUI 构建目标

使用 PyQT5 为 gma(以栅格重采样为例)构造一个 GUI 界面_第1张图片

GUI 代码

第一步:引入库

import sys
from PyQt5.QtWidgets import *
from gma import rasp, config
from gma.algorithm.core.dataio import Open

from gma.relation import key
from PyQt5.QtGui import QDoubleValidator, QFont
from style import *
import datetime as dt

第二步:依据 GUI 布局,配置一些基本位置参数

# 初始 X, 初始Y
StartX = 30
StartY = 30

# 行数,行宽
Line = 12
LineY = 50

WindowsSizeX = 640

# 结束 X
EndX = WindowsSizeX - StartX

# 每字符长度
FontLen = 12

# 文件按钮的宽度
FileBW = 80

# 行方向:每个内容的间距
HH = 20

# 计算窗体尺寸
WindowsSize = (WindowsSizeX, StartY + LineY * Line)

# 计算每一行的初始 **Y** 位置
iLineS = [StartY + i * LineY for i in range(Line)]

第三步:定义 gma 方法,时间获取函数和进度条函数

# 方法
RASPMethod = rasp.Resample

def GetCurrentTime():
    '''获取当前时间'''
    CurrentTime = dt.datetime.now()
    CurrentTimeString = CurrentTime.strftime("%Y-%m-%d %H:%M:%S")   
    
    return CurrentTimeString
    
# 进度条,以供调用
class ProgressBar(QWidget):
    def __init__(self):
        
        super(ProgressBar, self).__init__()
        self.PBar = QProgressBar(self)
        PX, PY = StartX, int(iLineS[-1] + LineY * 0.22)
        PW, PH = EndX - StartX, 20
        self.PBar.setGeometry(PX, PY, PW, PH)
        
        # self.PBar.setStyleSheet(ProgressBarStyle)
        self.PBar.setValue(0)
        
    def SetValue(self, Value):
        self.PBar.setValue(Value)

第四步:GUI 窗体配置


class MainWindow(QMainWindow, ProgressBar):

    def __init__(self):
        super().__init__()
        
        # 配置窗口
        self.setFixedSize(*WindowsSize)
        self.setStyleSheet("background-color: white;")  # 设置窗口背景为白色  
        self.setWindowTitle('GMA 栅格处理 — 重采样')
        
        # 配置图标
        self.setWindowIcon(LogoIcon)
        
        # 配置第一行
        self.InFileUI(0)
        self.UI2()
        self.UI3()
        self.UI4()
        self.OutFileUI(4)
        self.TextEdit(5)

        self.Center() # 将窗口居中
        self.show() # 显示窗口
        
    def TextEdit(self, Line = -4):
        self.TEdit = QTextEdit(self)
        
        SY = iLineS[Line] 
        
        # 创建标签
        L51 = "运行记录:"
        self.Label51 = QLabel(L51, self)
        self.Label51.move(StartX, SY)   
        
        X62, Y62, W62 = StartX, int(SY + LineY * 0.6), WindowsSizeX - StartX * 2
        H62 = int(LineY * 6 - LineY * 0.6)
        self.TEdit.setGeometry(X62, Y62, W62, H62) 
        self.TEdit.setReadOnly(True)
        

    def InFileUI(self, Line = 0):
        '''第一行的 UI 配置'''
        SY = iLineS[Line]
        
        # 创建标签
        L11 = "输入栅格:"
        X11, Y11 = StartX, SY
        self.Label11 = QLabel(f'*{L11}', self)
        self.Label11.move(X11, Y11)   

        # 创建文本框
        X12, Y12 = int(FontLen * len(L11) + FontLen * 0.5) + StartX + HH, SY
        W12, H12 = EndX - X12 - FileBW - HH, 30
        self.LineEdit12 = QLineEdit(self)
        self.LineEdit12.setGeometry(X12, Y12, W12, H12)
        self.LineEdit12.setReadOnly(True)
        self.LineEdit12.setStyleSheet("background-color: white;")
        
        # 创建按钮
        X13, Y13 = X12 + W12 + HH, SY
        W13, H13 = FileBW, 30        
        self.Button13 = QPushButton("...",  self)
        self.Button13.setGeometry(X13, Y13, W13, H13)
        self.Button13.clicked.connect(self.OpenRasterDialog)
        self.Button13.setStyleSheet(ButtonStyle)
        self.Button13.setIcon(FolderIcon)
           
    def UI2(self):
        '''第二行的 UI 配置'''
        SY = iLineS[1]
        
        # 标签 1
        L21 = "分辨率:"
        X21, Y21 = StartX, SY
        self.Label21 = QLabel(f'*{L21}', self)
        self.Label21.move(X21, Y21)  
        
        # 文本框 1
        X22, Y22 = int(FontLen * len(L21) + FontLen * 0.5) + StartX + HH, SY
        W22, H22 = int(WindowsSizeX * 0.5) - X22 - HH, 30
        self.LineEdit22 = QLineEdit(self)
        self.LineEdit22.setGeometry(X22, Y22, W22, H22)
        self.LineEdit22.setValidator(QDoubleValidator())
        
        # 标签 2
        L23 = "重采样方法:"
        X23, Y23 = X22 + W22 + HH, SY
        self.Label23 = QLabel(L23, self)
        self.Label23.move(X23, Y23) 
        
        # 选择器 1
        X24, Y24 = X23 + FontLen * len(L23) + HH, SY
        Width = EndX - X24
        self.ComboBox24 = QComboBox(self)
        self.ComboBox24.setGeometry(X24, Y24, Width, 30)
        self.ComboBox24.setStyleSheet(QComboBoxBarStyle)
        
        Method = key.ResampleMethod.keys()
        self.ComboBox24.addItems(Method)

    def UI3(self):
        '''第三行的 UI 配置'''
        SY = iLineS[2]
        
        # 标签 1
        L31 = "输入无效值:"
        X31, Y31 = StartX, SY
        self.Label31 = QLabel(L31, self)
        self.Label31.move(StartX, SY) 
        
        # 文本框 1
        X32, Y32 = FontLen * len(L31) + StartX + HH, SY
        W32, H32 = int(WindowsSizeX * 0.5 - X32 - HH), 30
        self.LineEdit32 = QLineEdit(self)
        self.LineEdit32.setGeometry(X32, Y32, W32, H32)   
        self.LineEdit32.setValidator(QDoubleValidator())

        # 标签 2
        L33 = "输出无效值:"
        X33, Y33 = X32 + W32 + HH, SY
        self.Label33 = QLabel(L33, self)
        self.Label33.move(X33, Y33) 
        
        # 文本框 2
        X34, Y34 = FontLen * len(L33) + X33 + HH, SY
        W34, H34 = EndX - X34, 30
        self.LineEdit34 = QLineEdit(self)
        self.LineEdit34.setGeometry(X34, Y34, W34, H34)   
        self.LineEdit34.setValidator(QDoubleValidator())
        
    def UI4(self):
        '''第四行的 UI 配置'''
        SY = iLineS[3]
        
        # 创建标签
        
        L41 = "输出栅格:"
        X41, Y41 = StartX, SY
        self.Label41 = QLabel(f'*{L41}', self)
        self.Label41.move(X41, Y41)   

        # 创建文本框
        X42, Y42 = int(FontLen * len(L41) + FontLen * 0.5 + StartX + HH), SY
        W42, H42 = EndX - X42 - FileBW - HH, 30
        self.LineEdit42 = QLineEdit(self)
        self.LineEdit42.setGeometry(X42, Y42, W42, H42)
        self.LineEdit42.setReadOnly(True)
        self.LineEdit42.setStyleSheet("background-color: white;")

        # 创建按钮
        X43, Y43 = X42 + W42 + HH, SY
        W43, H43 = FileBW, 30          
        self.Button43 = QPushButton("...",  self)
        self.Button43.setGeometry(X43, Y43, W43, H43)
        self.Button43.clicked.connect(self.WriteRasterDialog)
        self.Button43.setStyleSheet(ButtonStyle)
        self.Button43.setIcon(FolderIcon)    

    def OutFileUI(self, Line = -1):

        # 添加运行按钮 1 
        SY = iLineS[Line]

        X1 = 100
        Width = 100
        
        self.RButton = QPushButton('运行', self)
        self.RButton.setGeometry(X1, SY, Width, 30)
        self.RButton.clicked.connect(self.Run)
        self.RButton.setStyleSheet(ButtonStyle)
        self.RButton.setIcon(RunIcon)  
        
        # 添加运行按钮 1 
        X2 = WindowsSizeX - X1 - Width
        self.CButton = QPushButton('清空', self)
        self.CButton.setGeometry(X2, SY, Width, 30)
        self.CButton.clicked.connect(self.Reset)
        self.CButton.setStyleSheet(ButtonStyle)
        self.CButton.setIcon(ClearIcon)
  
    def Center(self):
        # 获取屏幕坐标系
        QR = self.frameGeometry()
        CP = QDesktopWidget().availableGeometry().center()
        QR.moveCenter(CP)
        self.move(QR.topLeft())
    
    def Reset(self):
        
        self.LineEdit12.clear()
        self.LineEdit42.clear()
        self.LineEdit22.clear()
        self.LineEdit32.clear()
        self.LineEdit34.clear()
        self.TEdit.clear()
        self.PBar.setValue(0)
        
    def Run(self):
        
        try:
            PAR = self.CheckPAR()
        except:
            self.TEdit.append(f'{GetCurrentTime()} || 带 * 的必选参数不能为空!')
            return 
        try:
            def WarpProgress(progress, message, callback_data):
                self.PBar.setValue(progress * 100)

                QApplication.processEvents()
                
            rasp._rasp.CallBack = WarpProgress
            rasp._rasp.CallBackData = self.PBar
            
            self.TEdit.append(f'{GetCurrentTime()} || 开始处理...')
            RASPMethod(*PAR)
            self.TEdit.append(f'{GetCurrentTime()} || 处理完成 {PAR}!')
        except Exception as E:   
            self.TEdit.append(f'{GetCurrentTime()} || gma 错误:{E}')
    
    def CheckPAR(self):
        '''检查参数!'''
        InFile = self.LineEdit12.text()
        OutFile = self.LineEdit42.text()

        Resolution = eval(self.LineEdit22.text())
        Method = self.ComboBox24.currentText()
        try:
            InNoData = eval(self.LineEdit32.text())
        except:
            InNoData = None
        try:
            OutNoData = eval(self.LineEdit34.text())    
        except:
            OutNoData = None

        return InFile, OutFile, Resolution, Method, InNoData, OutNoData, self.Format
        
    def OpenRasterDialog(self):
        # 打开文件选择对话框
        SFormat = sorted(config.RasterFormatInfo().ReadableFormats)

        SInfos = [f'*{GetEXTFromDriver(f)}' for f in SFormat if GetEXTFromDriver(f) != '']  
        SInfo = ' '.join(SInfos)
        
        FilePath, _ = QFileDialog.getOpenFileName(self, '打开文件', '.', f'栅格文件 ({SInfo})')
        
        if FilePath:

            try:
                self.DataSet = Open(FilePath)
            except:
                self.TEdit.append(f'{GetCurrentTime()} || 无法打开栅格文件:{FilePath}')
                return
            self.LineEdit12.setText(FilePath)
            FBL = str(round(self.DataSet.GeoTransform[1], 6))
            self.LineEdit22.setText(FBL)
    
            NoData = str(self.DataSet.NoData)
            self.LineEdit32.setText(NoData)
            self.LineEdit34.setText(NoData)


    def WriteRasterDialog(self):
        # 保存文件选择对话框
        SFormat = sorted(config.RasterFormatInfo().CreatableFormats)
 
        SInfos = [f'{f} 文件 (*{GetEXTFromDriver(f)})' for f in SFormat if GetEXTFromDriver(f) != '']  
        SInfo = ';;'.join(SInfos)
        
        FilePath, _ = QFileDialog.getSaveFileName(self, '保存文件', '.', SInfo)
        
        if FilePath:
            self.Format = _.split()[0]
            self.LineEdit42.setText(FilePath)
        else:
            self.Format = ''          
       
def GetEXTFromDriver(Drive):
    Drive = key.GetRasterEXTFromDriver(Drive)
    return Drive

第五步:定义工程入口


if __name__ == '__main__':
    APP = QApplication(sys.argv)
    Font = QFont('Microsoft YaHei', 9) # 创建一个微软雅黑字体
    APP.setFont(Font) # 将默认字体设置为微软雅黑
    APP.setStyle('Fusion')
    Window = MainWindow()
    sys.exit(APP.exec_())

结果示例

选择栅格文件界面

使用 PyQT5 为 gma(以栅格重采样为例)构造一个 GUI 界面_第2张图片

保存栅格文件界面

使用 PyQT5 为 gma(以栅格重采样为例)构造一个 GUI 界面_第3张图片

程序运行界面

使用 PyQT5 为 gma(以栅格重采样为例)构造一个 GUI 界面_第4张图片

你可能感兴趣的:(qt,python,开发语言)