2021年1月20日星期三

QLineEdit not updating text on clicked

I have been struggling a bit to structure the classes when multiple "pages" are involved (i.e. Login page, etc.).

I've looked through quite a few Stack Overflow posts and none of them seem to unlock the issue for me unfortunately.

I have a crypto trading bot that I am building a GUI for. There's a number of elements to this, but the bit that I am confused about at the moment can be seen in the below snip of code - I have a QWidget class consisting of 2 Group Boxes each holding other elements:

class bot_setup(QWidget):  refresh = QtCore.pyqtSignal()  def __init__(self,parent=None):      super(bot_setup,self).__init__(parent)      self.db = DATABASE      self.create_bot_label = QGroupBox("Create New Bot:",self)      self.view_bots_label = QGroupBox("Active Bots:",self)      self.main_grid = QGridLayout(self)      self.main_grid.addWidget(self.create_bot_label,0,1)      self.main_grid.addWidget(self.view_bots_label,0,0)        self.new_bot_space()      self.TableBot()    def new_bot_space(self):      create_bot_layout = QVBoxLayout(self)      self.bot_name_label = QLabel("Name:",self)      self.bot_name = QLineEdit(self)      self.strategy_name_label = QLabel("Strategy:",self)      self.strategy_name = QLineEdit(self)      self.interval_label = QLabel("Interval:",self)      self.interval = QLineEdit(self)      self.trade_allocation_label = QLabel("Trade Value",self)      self.trade_allocation = QLineEdit(self)      self.trailer_label = QLabel("Traling SL")      self.trailer = QLineEdit(self)      self.save_bot = QPushButton("Save Bot",self)      create_bot_layout.addWidget(self.bot_name_label)      create_bot_layout.addWidget(self.bot_name)      create_bot_layout.addWidget(self.strategy_name_label)      create_bot_layout.addWidget(self.strategy_name)      create_bot_layout.addWidget(self.interval_label)      create_bot_layout.addWidget(self.interval)      create_bot_layout.addWidget(self.trade_allocation_label)      create_bot_layout.addWidget(self.trade_allocation)      create_bot_layout.addWidget(self.trailer_label)      create_bot_layout.addWidget(self.trailer)      create_bot_layout.addWidget(self.save_bot)        self.create_bot_label.setLayout(create_bot_layout)      self.save_bot.clicked.connect(self.createNew)    def TableBot(self):      self.bots = self.db.GetAllBots()      self.tableWidget = QTableWidget(self)        self.tableWidget.setColumnCount(7)      self.tableWidget.setRowCount(len(self.bots)+1)      self.tableWidget.setItem(0,0,QTableWidgetItem("ID"))      self.tableWidget.setItem(0,1,QTableWidgetItem("Bot Name"))      self.tableWidget.setItem(0,2,QTableWidgetItem("Strategy"))      self.tableWidget.setItem(0,3,QTableWidgetItem("Interval"))      self.tableWidget.setItem(0,4,QTableWidgetItem("Trade Allocation"))      self.tableWidget.setItem(0,5,QTableWidgetItem("Trailing Stop Loss"))      self.tableWidget.setItem(0,6,QTableWidgetItem("Run"))      i = 0      for bot in self.bots:          self.bot_id = bot['id']          self.bot_name = bot['name']          self.strategy = bot['strategy_name']          self.interval = bot['interval']          self.trade_allocation = bot['trade_allocation']          self.stop_loss = bot['loss_margin']          self.tableWidget.setItem(i+1,0,QTableWidgetItem(self.bot_id))          self.tableWidget.setItem(i+1,1,QTableWidgetItem(self.bot_name))          self.tableWidget.setItem(i+1,2,QTableWidgetItem(self.strategy))          self.tableWidget.setItem(i+1,3,QTableWidgetItem(self.interval))          self.tableWidget.setItem(i+1,4,QTableWidgetItem(self.trade_allocation))          self.tableWidget.setItem(i+1,5,QTableWidgetItem(self.stop_loss))          self.tick_box = QTableWidgetItem()          self.tick_box.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)          self.tick_box.setCheckState(QtCore.Qt.Unchecked)          self.LastStateRole = QtCore.Qt.UserRole          self.tick_box.setData(self.LastStateRole, self.tick_box.checkState())          self.tableWidget.setItem(i+1,6,self.tick_box)          i = i+1      self.table_layout = QVBoxLayout(self)      self.view_bots_label.setLayout(self.table_layout)      self.select_bots = QPushButton("Select Bot/s",self)        self.table_layout.addWidget(self.tableWidget)      self.table_layout.addWidget(self.select_bots)    def createNew(self):      self.name = self.bot_name.text()      self.strategy_name = self.strategy_name.text()      self.interval = self.interval.text()      self.trade_allocation = self.trade_allocation.text()      self.trailer = self.trailer.text()        bot_id = str(uuid1())      bot_params = dict(          id = bot_id,          name = self.name,          strategy_name = self.strategy_name,          interval = self.interval,          trade_allocation = Decimal(self.trade_allocation),          loss_margin = Decimal(self.trailer),          active = True      )        self.db.SaveBot(bot_params)      for symbol in SYMBOLS:          pair_id = str(uuid1())          pair_params = dict(              id = pair_id,              bot_id = bot_id,              symbol = symbol,              is_active = True,              current_order_id = None,              profit_loss = Decimal(1)          )          self.db.SavePair(pair_params)      self.refresh.emit()    def onCellChanged(self):        rows = self.bot_setup_page.tableWidget.rowCount()        for row in range(1,rows):          item = self.bot_setup_page.tableWidget.item(row, 6)          last_state = item.data(self.LastStateRole)          current_state = item.checkState()          if last_state != current_state:              if current_state == QtCore.Qt.Checked:                  print("item checked!")                  bot_id = self.bot_setup_page.tableWidget.item(row,0).text()                  self.selected_bot_params.append(bot_id)                  print(self.selected_bot_params)              elif last_state == QtCore.Qt.Checked and \                  current_state == QtCore.Qt.Unchecked:                  bot_id = self.bot_setup_page.tableWidget.item(row,0).text()                  self.selected_bot_params.remove(bot_id)                  print(self.selected_bot_params)                  print("no check")                item.setData(self.LastStateRole,current_state)  

new_bot_space sets up the widgets to set up a new bot in the database by choosing parameters (QLabel, QLineEdit). The idea was to capture the text in the LineEdits when the save_bot QPushButton is clicked by calling on the createNew function to read the text from the LineEdits and insert them into the database.

The widget is then called by the below code:

class MainWindow(QMainWindow):    def __init__(self, parent=None):      super(MainWindow,self).__init__(parent)        toolbar = QToolBar("MainToolbar")      self.addToolBar(toolbar)      logout_btn = QAction("Logout", self)      logout_btn.setStatusTip("Button")      logout_btn.triggered.connect(self.quit_session)      live_btn = QAction("Run Live",self)      live_btn.setStatusTip("Live")      live_btn.triggered.connect(self.load_live)      backtest_btn = QAction("Backtest",self)      backtest_btn.setStatusTip("test bot")      backtest_btn.triggered.connect(self.backtester_page)      botCreate_btn = QAction("Create New Bot",self)      botCreate_btn.setStatusTip("Create Bot")      botCreate_btn.triggered.connect(self.create_new_bot)      toolbar.addAction(logout_btn)      toolbar.addAction(botCreate_btn)      toolbar.addAction(live_btn)      toolbar.addAction(backtest_btn)      self.login_page()    def login_page(self):      self.login_widgets = LoginWindow(self)        self.setCentralWidget(self.login_widgets)      self.setGeometry(300,300,300,300)      self.setWindowTitle("Welcome!")      self.show()    def quit_session(self):      pass    def load_live(self):      pass    def backtester_page(self):      pass    def create_new_bot(self):      self.bot_creation = bot_setup(self)      self.bot_creation.refresh.connect(self.refreshBotSetup)      self.setCentralWidget(self.bot_creation)      self.setGeometry(300,300,800,800)      self.setWindowTitle("Setup New Bot")      self.show()    def refreshBotSetup(self):      self.bot_creation.bot_name = None      self.bot_creation.strategy_name = None      self.bot_creation.interval = None      self.bot_creation.trade_allocation = None      self.bot_creation.trailer = None        self.create_new_bot()  

Def main():

app = QApplication(sys.argv)    w = MainWindow()    sys.exit(app.exec_())  

When I run the code and input parameters and click save, the first time I get the expected outcome, however when I have created 1 bot in the database if I try to create another one it doesn't read new input correctly - its almost as if it has stored the previous instance of .text() and as such the inputs are already type string and the code errors out with the below traceback:

    t  Traceback (most recent call last):    File "AppV2.py", line 128, in createNew      self.name = self.bot_name.text()  AttributeError: 'str' object has no attribute 'text'  

The 't' is the last line of the output where I print self.bot_name before I define self.name and on this occasion of running the script the value input was not 't' so even when the script has stopped and re-run it has stored the input from the first session.

NOTE I have tried a different structure of the code which worked - that was by doing the .clicked.connect signal within the MainWindow class and calling on the createNew function also within the MainWindow class. I felt this was a bit messy so I was hoping to encapsulate all of the functions for each widget within the same QWidget class

https://stackoverflow.com/questions/65819767/qlineedit-not-updating-text-on-clicked January 21, 2021 at 08:56AM

没有评论:

发表评论