2023年7月3日 星期一

【Python交易程式開發現場29】在VS Code中使用Python虛擬環境之問題解決 | virtualenv .venv|

結論:

1. 於vs code Terminal下執行: pip3 install virtualenv
2. 於vs code Terminal下執行: virtualenv .venv
3. 於vs code右下方,將python 環境切換到虛擬環境

為什麼需要虛擬環境(Virtual Environment)?

虛擬環境是一個類似沙盒(Sandbox)的概念。透過建立獨特於每個 Python 專案的虛擬環境,我們可以在不影響其他專案的情況下,控制:

  • 這個專案使用的 Python 版本
  • 這個專案安裝並使用的 Python libraries
  • 這個專案的 Python 偏好設定

試想像我們有兩個專案:專案 A 使用大量的 Python libraries,而專案 B 使用少量的 Python libraries。當我們部署(Deploy)這 2 個專案到伺服器時,我們需要要求每個伺服器安裝所需的 Python libraries。如果我們沒有以虛擬環境分隔專案 A 與專案 B,則專案 B 會安裝大量無需的 Python libraries。

更甚的是假如專案 A 的 libraries 不相容於專案 B,那麼我們沒有虛擬環境下,便不能運行專案 B(因為我們沒有專案 B 所需的 libraries)。

VSCode 2/5: 設定虛擬環境 Virtual Env,管理 Python 專案!


Step 0: (optional) 備份虛擬環境資料

pip3 freeze > requirements.txt


[VS Code] 在專案中啟用 Python 虛擬環境


Step 1: pip3 install virtualenv



第 2 步:在文件夾建立虛擬環境

在 TERMINAL 輸入以下的代碼,並按一下 Return(Enter):

virtualenv .venv




Terminal 完成處理後,您應該見到左邊的 Explorer 裡多了「.venv」的文件夾。這是我們虛擬環境的文件夾,用以安裝所需 Python libraries。



如果你需要將原本備份好的工作環境環境,可以使用以下指令:

pip3 install requirements.txt 


有問題, 改以下:

pip3 install -r requirements.txt

[VS Code] 在專案中啟用 Python 虛擬環境

How to install Python packages with pip and requirements.txt


PowerShell - 解決 ".ps1 檔案無法載入,因為這個系統上已停用指令碼執行。" 問題











Python 初級:Virtual Environment 虛擬環境|教學|廣東話|60fps


問題:ModuleNotFoundError: No module named ‘comtypes.gen.SKCOMLib’

第一、原因:python 版本問題(3.8 不能)

第二、註冊問題(SKCOM.dll 要和主程式同目錄)

import comtypes.client 
comtypes.client.GetModule(os.path.split(os.path.realpath(__file__))[0] + r'\SKCOM.dll')








2023年7月2日 星期日

【Python交易程式開發現場27】使用QTableWidget顯示倉位(1) | 使用Qt Designer拉UI

 



參考資訊: 【Day06】QTableWidget 表格 with Images 圖片


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(754, 605)
        self.listWidget = QtWidgets.QListWidget(parent=Form)
        self.listWidget.setGeometry(QtCore.QRect(10, 100, 731, 151))
        self.listWidget.setObjectName("listWidget")
        self.gridLayoutWidget = QtWidgets.QWidget(parent=Form)
        self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 731, 80))
        self.gridLayoutWidget.setObjectName("gridLayoutWidget")
        self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton_3 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_3.setObjectName("pushButton_3")
        self.gridLayout.addWidget(self.pushButton_3, 1, 2, 1, 1)
        self.pushButton = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
        self.pushButton_7 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_7.setObjectName("pushButton_7")
        self.gridLayout.addWidget(self.pushButton_7, 0, 3, 1, 1)
        self.pushButton_8 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_8.setObjectName("pushButton_8")
        self.gridLayout.addWidget(self.pushButton_8, 0, 4, 1, 1)
        self.pushButton_6 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_6.setObjectName("pushButton_6")
        self.gridLayout.addWidget(self.pushButton_6, 1, 3, 1, 1)
        self.pushButton_5 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_5.setObjectName("pushButton_5")
        self.gridLayout.addWidget(self.pushButton_5, 0, 2, 1, 1)
        self.pushButton_4 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_4.setObjectName("pushButton_4")
        self.gridLayout.addWidget(self.pushButton_4, 1, 1, 1, 1)
        self.pushButton_2 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 0, 1, 1, 1)
        self.gridLayout_2 = QtWidgets.QGridLayout()
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.pushButton_10 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_10.setObjectName("pushButton_10")
        self.gridLayout_2.addWidget(self.pushButton_10, 0, 1, 1, 1)
        self.pushButton_9 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_9.setObjectName("pushButton_9")
        self.gridLayout_2.addWidget(self.pushButton_9, 0, 0, 1, 1)
        self.pushButton_11 = QtWidgets.QPushButton(parent=self.gridLayoutWidget)
        self.pushButton_11.setObjectName("pushButton_11")
        self.gridLayout_2.addWidget(self.pushButton_11, 0, 2, 1, 1)
        self.gridLayout.addLayout(self.gridLayout_2, 0, 8, 1, 1)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
        self.gridLayout.addItem(spacerItem, 0, 5, 1, 1)
        self.tableWidget = QtWidgets.QTableWidget(parent=Form)
        self.tableWidget.setGeometry(QtCore.QRect(10, 260, 731, 331))
        self.tableWidget.setRowCount(10)
        self.tableWidget.setColumnCount(12)
        self.tableWidget.setObjectName("tableWidget")
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        self.tableWidget.horizontalHeader().setVisible(True)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton_3.setText(_translate("Form", "3-查詢"))
        self.pushButton.setText(_translate("Form", "1-登入"))
        self.pushButton_7.setText(_translate("Form", "6-畫1分K"))
        self.pushButton_8.setText(_translate("Form", "7- 畫Tcik圖"))
        self.pushButton_6.setText(_translate("Form", "5-查即時Tick"))
        self.pushButton_5.setText(_translate("Form", "4-查歷史Tick"))
        self.pushButton_4.setText(_translate("Form", "報價斷線"))
        self.pushButton_2.setText(_translate("Form", "2-報價連線"))
        self.pushButton_10.setText(_translate("Form", "10-讀取憑證"))
        self.pushButton_9.setText(_translate("Form", "9-下單啟動"))
        self.pushButton_11.setText(_translate("Form", "11-倉位查詢"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("Form", "商品代號"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("Form", "價格"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("Form", "現在價格"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("Form", "成本價格"))
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText(_translate("Form", "賺賠"))



class MyMainWindow(QMainWindow, Ui_Form):
    def __init__(self, parent=None):    
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.twTest1) #ctw signal
        self.pushButton_2.clicked.connect(self.twTest2) #ctw signal
        self.pushButton_3.clicked.connect(self.twTest3) #ctw signal
        self.pushButton_4.clicked.connect(self.twTest8) #ctw signal
        self.pushButton_5.clicked.connect(self.twTest4) #ctw signal
        self.pushButton_6.clicked.connect(self.twTest5) #ctw signal      
        self.pushButton_7.clicked.connect(self.twTest6) #ctw signal
        self.pushButton_8.clicked.connect(self.twTest7) #ctw signal
        self.pushButton_9.clicked.connect(self.twTest9) #ctw signal    
        self.pushButton_10.clicked.connect(self.twTest10) #ctw signal  
        self.pushButton_11.clicked.connect(self.twTest11) #ctw signal    


    def twTest1(self):  #ctw slot function
        print("1-登入")    
        self.listWidget.addItem("1-登入")
        twLogin(ID, PW)

    def twTest2(self):  #ctw slot function
        print("2-連線")    
        self.listWidget.addItem("2-連線")
        self.listWidget.addItem("m_nCode: " + str(twConnect()))

##############################################################################
#  Qt Signal/Slot
##############################################################################

# 信号对象
class QTypeSignal(QObject):
    # 定义一个信号
    sendmsg = pyqtSignal(object)

    def __init__(self):
        super(QTypeSignal, self).__init__()  #super() 函数是用于调用父类(超类)的一个方法。

    def run(self, msg):
        # 发射信号
        self.sendmsg.emit(msg)


# 槽对象          
class QTypeSlot(QObject):
    def __init__(self):
        super(QTypeSlot, self).__init__()

        # 槽对象里的槽函数

    def get(self, msg):
        #print("QSlot get msg => ")
        myWin.showMessage(msg)

    def OnNotifyQuoteLONG(self, sMarketNo, nStockidx):    #ctw # 3-【查詢】回報    
        pStock = sk.SKSTOCKLONG()
        m_nCode = skQ.SKQuoteLib_GetStockByIndexLONG(sMarketNo, nStockidx, pStock)
        strMsg = '代碼:',pStock.bstrStockNo,'--名稱:',pStock.bstrStockName,'--開盤價:',str(pStock.nOpen/math.pow(10,pStock.sDecimal)),'--最高:',\
            str(pStock.nHigh/math.pow(10,pStock.sDecimal)),'--最低:',\
            str(pStock.nLow/math.pow(10,pStock.sDecimal)),'--成交價:',str(pStock.nClose/math.pow(10,pStock.sDecimal))\
            ,'--總量:',str(pStock.nTQty)
               
        twStrMsg=twTuple_2_Str(strMsg)
        send.run(twStrMsg)

##############################################################################
# 主程式
##############################################################################

if __name__=="__main__":  
    app = QApplication(sys.argv)  
    myWin = MyMainWindow()  
    myWin.show()  

    send = QTypeSignal()
    slot = QTypeSlot()
   
    # 1
    print('--- 把信号绑定到槽函数 ---')
    send.sendmsg.connect(slot.get)
    #send.run()

    # 2
    #print('--- 把信号断开槽函数 ---')
    #send.sendmsg.disconnect(slot.get)
    #send.run()

    sys.exit(app.exec())  

class MyMainWindow(QMainWindow, Ui_Form):
    def __init__(self, parent=None):    
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.twTest1) #ctw signal
        self.pushButton_2.clicked.connect(self.twTest2) #ctw signal
        self.pushButton_3.clicked.connect(self.twTest3) #ctw signal
        self.pushButton_4.clicked.connect(self.twTest8) #ctw signal
        self.pushButton_5.clicked.connect(self.twTest4) #ctw signal
        self.pushButton_6.clicked.connect(self.twTest5) #ctw signal      
        self.pushButton_7.clicked.connect(self.twTest6) #ctw signal
        self.pushButton_8.clicked.connect(self.twTest7) #ctw signal
        self.pushButton_9.clicked.connect(self.twTest9) #ctw signal    
        self.pushButton_10.clicked.connect(self.twTest10) #ctw signal  
        self.pushButton_11.clicked.connect(self.twTest11) #ctw signal    

    def twTest1(self):  #ctw slot function
        print("1-登入")    
        self.listWidget.addItem("1-登入")
        twLogin(ID, PW)


    def twTest11(self):  #ctw slot function
        print("11-倉位查詢")    
        self.listWidget.addItem("9-倉位查詢")
        self.listWidget.addItem("m_nCode1: " + str(twSKO3_GetAccount()))  
        self.listWidget.addItem("m_nCode2: " + str(twSKO4_GetOpenInterest(ID, ACCOUNT)))  
        self.tableWidget.setItem(1,1,QTableWidgetItem("倉位查詢"))
        #listWidget.addItem("m_nCode2: " + str(twSKO4_GetOpenInterest(ID, ACCOUNT)))  
        #self.listWidget.addItem("m_nCode: " + str(twDisconnect()))  

    def showMessage(self, msg):
        self.listWidget.addItem(msg)

        #global GlobalListInformation,Global_ID
        #GlobalListInformation = self.listWidget
        #Global_ID = self.labelID    



prog-0318

test test1 Written with StackEdit .