2016-07-22 51 views
1

我在我的應用程序中使用QLineEdit小部件來輸入和編輯數字(浮點)值。我想顯示浮點值的舍入版本,同時保持完整的內部準確性。只有在編輯QLineEdit字段時,應該顯示完整的數字位數。在不犧牲內部準確性的情況下限制pyQT QLineEdit中顯示的浮點數的數量

這是必要的,原因有三:

  • 複雜的值需要太多的空間,我的GUI

  • 的UI允許日誌和線性表示,我想隱藏之間選擇由此產生的數字不準確。

  • 編輯所顯示的數值時,只需四捨五入包含並顯示在QLineEdit的價值並不像我會失去精度的選擇

是否有人知道這個問題的巧妙的解決辦法?

下面你會發現一個MWE,完整的代碼(pyfda)使用小部件和其他醜陋的東西的動態實例化。

# -*- coding: utf-8 -*- 
from __future__ import print_function, division 
import numpy as np 
import sys 
from PyQt4 import QtGui 

class InputNumFields(QtGui.QWidget): 

    def __init__(self, parent): 
     super(InputNumFields, self).__init__(parent) 
     self.edit_input_float = 10*np.log10(np.pi) # store in log format 
     self._init_UI() 

    def _init_UI(self):  
     self.edit_input = QtGui.QLineEdit() 
     self.edit_input.editingFinished.connect(self.store_entries) 
     self.lay_g_main = QtGui.QGridLayout() 
     self.lay_g_main.addWidget(self.edit_input, 0, 0) 
     self.setLayout(self.lay_g_main) 
     self.get_entries() 

    def store_entries(self): 
     """ Store text entry as log float""" 
     self.edit_input_float = 10*np.log10(float(self.edit_input.text())) 
     self.get_entries() 

    def get_entries(self): 
     """ Retrieve float value, delog and convert to string """ 
     self.edit_input.setText(str(10**(self.edit_input_float/10))) 

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    mainw = InputNumFields(None) 
    app.setActiveWindow(mainw) 
    mainw.show() 
    sys.exit(app.exec_()) 
+0

您可以創建包含圓角版本的數量的另一變量,更新它當「主」數得到改變等 – Yegers

+0

呀,我曾考慮過保留所有變量的「影子副本」。但是,每次點擊它或顯示模式(lin/log/...)改變時,您都必須將未截斷的值複製回QLineEdit。我仍然希望有更簡單的解決方案... – Chipmuenk

回答

0

看來這個行爲應該是這樣的:

  • 當線路編輯失去輸入焦點,顯示存儲的值四捨五入
  • 當線路編輯收益輸入對焦,顯示儲存的全部數值
  • 無論何時編輯完成,以日誌格式存儲全部當前值

這意味着四捨五入肯定不是當按下return或enter時會發生(因爲在這種情況下行編輯不會失去焦點)。

上述行爲可以用下面的變化來實現:

from PyQt4 import QtCore, QtGui 

class InputNumFields(QtGui.QWidget): 
    ... 

    def _init_UI(self): 
     self.edit_input = QtGui.QLineEdit() 
     self.edit_input.installEventFilter(self) 
     ... 

    def eventFilter(self, source, event): 
     if (event.type() == QtCore.QEvent.FocusIn and 
      source is self.edit_input): 
      self.get_entries() 
     return super(InputNumFields, self).eventFilter(source, event) 

    def get_entries(self): 
     value = 10**(self.edit_input_float/10) 
     if not self.edit_input.hasFocus(): 
      value = round(value, 3) 
     self.edit_input.setText(str(value)) 

PS:

很可能需要添加一個按鈕或東西,你的榜樣,這樣你就可以測試改變焦點的效果。

+0

謝謝,我會在星期一嘗試。我沒有使用QEvent或eventFiltering,這絕對是一個新的知識塊! – Chipmuenk

0

我試過使用混合的信號插槽連接(editingFinished)和eventFilter。但是,我遇到了一些奇怪的錯誤,這些錯誤可能是由於某些競爭條件造成的,或者僅僅是因爲代碼背後的邏輯變得過於扭曲。不管怎樣,下面的代碼片段的偉大工程,也許是有幫助的人:

def eventFilter(self, source, event): 
    """ 
    Filter all events generated by the QLineEdit widgets. Source and type 
    of all events generated by monitored objects are passed to this eventFilter, 
    evaluated and passed on to the next hierarchy level. 

    - When a QLineEdit widget gains input focus (QEvent.FocusIn`), display 
     the stored value with full precision 
    - When a key is pressed inside the text field, set the `spec_edited` flag 
     to True. 
    - When a QLineEdit widget loses input focus (QEvent.FocusOut`), store 
     current value in linear format with full precision (only if 
     `spec_edited`== True) and display the stored value in selected format 
    """ 
    if isinstance(source, QtGui.QLineEdit): # could be extended for other widgets 
     if event.type() == QEvent.FocusIn: 
      self.spec_edited = False 
      self.get_entries() 
     elif event.type() == QEvent.KeyPress: 
      self.spec_edited = True 
     elif event.type() == QEvent.FocusOut: 
      self._store_entries(source) 
    # Call base class method to continue normal event processing: 
    return super(InputAmpSpecs, self).eventFilter(source, event) 
相關問題