Building PyQt5 GUIs for Keck Instruments
kPyQt
You should use the kPyQt module to streamline interactions with KTL keywords. The sphinx documentation for the module is here, including a working example similar to the complete example below:
https://www2.keck.hawaii.edu/software/kPyQt/
https://www2.keck.hawaii.edu/software/kPyQt/examples.html
Old Method:
Monitoring a keyword
Support we want to connect the monitoring of a keyword to a status text field.
The basic steps are:
# this part creates a thread not in Python but in the QT system
# the thread is used to create a KTL monitoring of the keyword fname from the
# server kbes. When the keyword changes, the filter_callback function is called
class keywordMonitor(QThread):
filter = pyqtSignal('QString')
def __init__(self):
QThread.__init__(self)
def __del__(self):
self.wait()
def run(self):
# this is the callback function that is triggered when the filter changes
# it "emits" a signal to the main thread, and sends the value of the
# keyword
def filter_callback(keyword):
value = keyword['binary']
self.filter.emit(str(value))
# this is the connection to ktl
filter = ktl.cache('kbes','fname')
filter.callback(filter_callback)
filter.monitor()
# this makes sure that the thread does not exit
while True:
self.sleep(1)
# here we are defining the main graphic window
class MyWindow(QWidget):
def __init__(self, *args):
super().__init__()
self.init_ui()
self.setWindowTitle("Example")
# here we start thread that monitors the keyword monitor, the one
# we have created at the beginning of this program
self.start_keyword_monitor()
def init_ui(self):
# create the labels and arrange them in a small window
self.label_filter = QLabel("Filter")
self.label_filter_result = QLabel("")
layout = QVBoxLayout()
layout.addWidget(self.label_filter)
layout.addWidget(self.label_filter_result)
self.setLayout(layout)
# this is called as part of the init procedure
# note that the connection is between filter.emit (further up)
# and filter.connect. Filter.emit sends a new value of the
# filter when it is received, filter.connect tells the main thread what to do
def start_keyword_monitor(self):
self.keyword_thread = keywordMonitor()
self.keyword_thread.filter.connect(self.update_filter)
set.keyword_thread.start()
# and this is the "what to do": once the signa is emitted and then received
# we trigger the function setText.
# this is not necessary. We could decide to send an email or anything else...
def update_filter(self, value):
self.label_filter_result.setText(value)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())