kcg_remote_client_qt.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. from PyQt4 import QtGui, QtCore
  2. import subprocess
  3. # import numpy as np
  4. # import pyqtgraph as pg
  5. # import cPickle
  6. import time
  7. import sys
  8. import kcg_remote_client as client
  9. def safe_call(cmd):
  10. try:
  11. return subprocess.check_output(cmd)
  12. except subprocess.CalledProcessError as e:
  13. pass
  14. except OSError as e:
  15. pass
  16. class settingHighlighter(QtGui.QSyntaxHighlighter):
  17. def __init__( self, parent, theme):
  18. super(settingHighlighter, self).__init__(parent)
  19. self.parent = parent
  20. self.highlightingRules = []
  21. # equal = QtGui.QTextCharFormat()
  22. # equal.setForeground(QtCore.Qt.green)
  23. # equal.setFontWeight( QtGui.QFont.Bold )
  24. # pattern = QtCore.QRegExp("=")
  25. # self.highlightingRules.append((pattern, equal))
  26. number = QtGui.QTextCharFormat()
  27. number.setForeground(QtCore.Qt.blue)
  28. number.setFontWeight( QtGui.QFont.Bold )
  29. pattern = QtCore.QRegExp( "[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?" )
  30. pattern.setMinimal(True)
  31. self.highlightingRules.append((pattern, number))
  32. bool_true = QtGui.QTextCharFormat()
  33. bool_true.setForeground(QtCore.Qt.darkGreen)
  34. bool_true.setFontWeight( QtGui.QFont.Bold )
  35. pattern = QtCore.QRegExp( "True" )
  36. self.highlightingRules.append((pattern, bool_true))
  37. bool_false = QtGui.QTextCharFormat()
  38. bool_false.setForeground(QtCore.Qt.darkRed)
  39. bool_false.setFontWeight( QtGui.QFont.Bold )
  40. pattern = QtCore.QRegExp( "False" )
  41. self.highlightingRules.append((pattern, bool_false))
  42. failed = QtGui.QTextCharFormat()
  43. failed.setForeground(QtCore.Qt.red)
  44. failed.setFontWeight( QtGui.QFont.Bold )
  45. pattern = QtCore.QRegExp( "Failed|Connection Error" )
  46. self.highlightingRules.append((pattern, failed))
  47. success = QtGui.QTextCharFormat()
  48. success.setForeground(QtGui.QColor(30, 210, 0))
  49. success.setFontWeight( QtGui.QFont.Bold )
  50. pattern = QtCore.QRegExp( "Success" )
  51. self.highlightingRules.append((pattern, success))
  52. header = QtGui.QTextCharFormat()
  53. header.setForeground(QtCore.Qt.black)
  54. header.setFontWeight( QtGui.QFont.Bold )
  55. pattern = QtCore.QRegExp( "-----\[.*\]-----" )
  56. pattern.setMinimal(True)
  57. self.highlightingRules.append((pattern, header))
  58. working = QtGui.QTextCharFormat()
  59. working.setForeground(QtCore.Qt.black)
  60. working.setFontWeight( QtGui.QFont.Bold )
  61. pattern = QtCore.QRegExp("Working...")
  62. self.highlightingRules.append((pattern, working))
  63. def setKeywords(self, kw):
  64. keyword = QtGui.QTextCharFormat()
  65. keyword.setForeground( QtCore.Qt.darkBlue)
  66. # keyword.setFontWeight( QtGui.QFont.Bold )
  67. keywords = QtCore.QStringList(kw)
  68. for word in keywords:
  69. pattern = QtCore.QRegExp("\\b" + word + "\\b")
  70. self.highlightingRules.append((pattern, keyword))
  71. def highlightBlock( self, text ):
  72. for pattern, format in self.highlightingRules:
  73. # expression = QtCore.QRegExp( pattern )
  74. # index = expression.indexIn( text )
  75. index = pattern.indexIn(text)
  76. while index >= 0:
  77. length = pattern.matchedLength()
  78. self.setFormat( index, length, format )
  79. index = text.indexOf( pattern, index + length )
  80. self.setCurrentBlockState( 0 )
  81. class customTextEdit(QtGui.QTextEdit):
  82. def __init__(self):
  83. super(customTextEdit, self).__init__()
  84. self.highlighter = settingHighlighter(self, 'Classic')
  85. def append(self, string):
  86. # super(customTextEdit, self).append("---------------"*3)
  87. super(customTextEdit, self).append("-----[ " + time.asctime() + " ]-----\n"+string+"\n")
  88. self.ensureCursorVisible()
  89. def setKeywords(self, kw):
  90. self.highlighter.setKeywords(kw)
  91. class convenientGridLayout(QtGui.QGridLayout):
  92. line = 0
  93. column = 0
  94. def addWidget(self, QWidget, newLine=False, line=None, col=None, rowSpan=1, colSpan=1):
  95. if (line is not None) and (col is not None):
  96. super(convenientGridLayout, self).addWidget(QWidget, line, col, rowSpan, colSpan)
  97. return
  98. elif line is not None:
  99. super(convenientGridLayout, self).addWidget(QWidget, line, self.column, rowSpan, colSpan)
  100. return
  101. elif col is not None:
  102. super(convenientGridLayout, self).addWidget(QWidget, self.line, col, rowSpan, colSpan)
  103. return
  104. if newLine:
  105. self.line += 1
  106. self.column = 0
  107. super(convenientGridLayout, self).addWidget(QWidget, self.line, self.column, rowSpan, colSpan)
  108. return
  109. else:
  110. super(convenientGridLayout, self).addWidget(QWidget, self.line, self.column, rowSpan, colSpan)
  111. self.column += 1
  112. return
  113. def newLine(self):
  114. self.line += 1
  115. self.column = 0
  116. def skipCol(self, cols=1):
  117. self.column += cols
  118. def hLine(self, cols):
  119. line = QtGui.QFrame()
  120. line.setFrameShape(QtGui.QFrame.HLine)
  121. if cols == 'full':
  122. self.addWidget(line, newLine=True, colSpan=self.columnCount())
  123. else:
  124. self.addWidget(line, newLine=True, colSpan=cols)
  125. def vLine(self, rows, perm=False):
  126. line = QtGui.QFrame()
  127. line.setFrameShape(QtGui.QFrame.VLine)
  128. if rows == 'full':
  129. self.addWidget(line, rowSpan=self.rowCount())
  130. else:
  131. self.addWidget(line, rowSpan=rows)
  132. class KCGRemote(QtGui.QMainWindow):
  133. def __init__(self):
  134. super(KCGRemote, self).__init__()
  135. self.c = KCGCentral()
  136. self.setCentralWidget(self.c)
  137. self.statusText = QtGui.QLabel("Not Connected")
  138. self.statusbar = self.statusBar()
  139. self.statusbar.addPermanentWidget(self.statusText)
  140. self.setWindowTitle("KCG Remote Control")
  141. if len(sys.argv) > 1 and sys.argv[1] == 'blue':
  142. styleSheet = ''
  143. with open('KCG/style/blue.css') as f:
  144. styleSheet += f.read()
  145. self.setStyleSheet(styleSheet)
  146. class KCGCentral(QtGui.QWidget):
  147. def __init__(self):
  148. super(KCGCentral, self).__init__()
  149. self.progressbar = QtGui.QProgressBar()
  150. self.progressbar.hide()
  151. # self.user_layout = QtGui.QGridLayout()
  152. self.user_layout = convenientGridLayout()
  153. self.layout = QtGui.QVBoxLayout()
  154. self.layout.addLayout(self.user_layout)
  155. self.setLayout(self.layout)
  156. self.host_edit = QtGui.QLineEdit()
  157. self.port_edit = QtGui.QLineEdit()
  158. self.connect = QtGui.QPushButton("Connect")
  159. self.connect.clicked.connect(self.conn)
  160. self.host = None
  161. self.port = None
  162. self.cal_button = QtGui.QPushButton("Calibrate")
  163. self.cal_button.clicked.connect(self.cal)
  164. self.sync_button = QtGui.QPushButton("Synchronize")
  165. self.sync_button.clicked.connect(self.sync)
  166. self.set_def_button = QtGui.QPushButton("Set Defaults")
  167. self.set_def_button.clicked.connect(self.set_def)
  168. self.reset_button = QtGui.QPushButton("Reset")
  169. self.reset_button.clicked.connect(self.reset)
  170. self.acquire_button = QtGui.QPushButton("Toggle Acquisition")
  171. self.acquire_button.clicked.connect(self.acq)
  172. self.get_button = QtGui.QPushButton("Get Value")
  173. self.get_button.clicked.connect(self.get)
  174. self.set_button = QtGui.QPushButton("Set Value")
  175. self.set_button.clicked.connect(self.set)
  176. self.reinit_status_button = QtGui.QPushButton("Reinit Status")
  177. self.reinit_status_button.clicked.connect(self.status)
  178. self.get_image_button = QtGui.QPushButton("Get Image")
  179. self.get_image_button.clicked.connect(self.get_image)
  180. # self.get_field = QtGui.QLineEdit()
  181. self.get_placeholder = QtGui.QLabel("Load possible keys first")
  182. self.set_key_placeholder_button = QtGui.QPushButton("Load possible keys")
  183. self.set_key_placeholder_button.clicked.connect(self.load_keys)
  184. self.set_value_field = QtGui.QLineEdit()
  185. self.get_image_type = QtGui.QComboBox()
  186. self.get_image_type.addItems(['trains', 'fft', 'heatmap', 'combined'])
  187. self.get_image_adc_field = QtGui.QSpinBox()
  188. self.get_image_adc_field.setRange(1, 4)
  189. self.single_read_button = QtGui.QPushButton("Single Read")
  190. self.single_read_button.clicked.connect(self.single_read)
  191. self.buttons = [self.cal_button,
  192. self.sync_button,
  193. self.set_def_button,
  194. self.reset_button,
  195. self.acquire_button,
  196. self.get_button,
  197. self.set_button,
  198. self.get_image_button,
  199. self.set_key_placeholder_button,
  200. self.reinit_status_button,
  201. self.get_image_type,
  202. self.get_image_adc_field,
  203. self.set_value_field,
  204. self.single_read_button]
  205. for b in self.buttons:
  206. b.setEnabled(False)
  207. # self.user_layout.addWidget(QtGui.QLabel("Host"), 0, 0)
  208. # self.user_layout.addWidget(self.host_edit, 1, 0)
  209. # self.user_layout.addWidget(QtGui.QLabel("Port"), 0, 1)
  210. # self.user_layout.addWidget(self.port_edit, 1, 1)
  211. # self.user_layout.addWidget(self.connect, 1, 3)
  212. # line = QtGui.QFrame()
  213. # line.setFrameShape(QtGui.QFrame.HLine)
  214. # self.user_layout.addWidget(line, 2, 0, 1, 4)
  215. # self.user_layout.addWidget(self.cal_button, 3, 0)
  216. # self.user_layout.addWidget(self.sync_button, 3, 1)
  217. # self.user_layout.addWidget(self.set_def_button, 4, 1)
  218. # self.user_layout.addWidget(self.reset_button, 4, 0)
  219. # line2 = QtGui.QFrame()
  220. # line2.setFrameShape(QtGui.QFrame.VLine)
  221. # self.user_layout.addWidget(line2, 3, 2, 2, 1)
  222. # line3 = QtGui.QFrame()
  223. # line3.setFrameShape(QtGui.QFrame.HLine)
  224. # self.user_layout.addWidget(line3, 5, 0, 1, 4)
  225. # self.user_layout.addWidget(self.acquire_button, 3, 3)
  226. # self.user_layout.addWidget(self.reinit_status_button, 4, 3)
  227. # self.user_layout.addWidget(self.get_image_type, 6, 0)
  228. # self.user_layout.addWidget(self.get_image_adc_field, 6, 1)
  229. # self.user_layout.addWidget(self.get_image_button, 6, 3)
  230. # self.user_layout.addWidget(self.get_placeholder, 7, 1)
  231. # self.user_layout.addWidget(self.get_button, 7, 3)
  232. # self.user_layout.addWidget(self.set_key_placeholder_button, 8, 0)
  233. # self.user_layout.addWidget(self.set_value_field, 8, 1)
  234. # self.user_layout.addWidget(self.set_button, 8, 3)
  235. self.user_layout.addWidget(QtGui.QLabel("Host"))
  236. self.user_layout.addWidget(QtGui.QLabel("Port"))
  237. self.user_layout.newLine()
  238. self.user_layout.addWidget(self.host_edit)
  239. self.user_layout.addWidget(self.port_edit)
  240. self.user_layout.addWidget(self.connect)
  241. # line = QtGui.QFrame()
  242. # line.setFrameShape(QtGui.QFrame.HLine)
  243. # self.user_layout.addWidget(line, newLine=True, colSpan=4)
  244. self.user_layout.hLine('full')
  245. self.user_layout.newLine()
  246. self.user_layout.addWidget(self.cal_button)
  247. self.user_layout.addWidget(self.sync_button)
  248. # line2 = QtGui.QFrame()
  249. # line2.setFrameShape(QtGui.QFrame.VLine)
  250. # self.user_layout.addWidget(line2, rowSpan=2)
  251. self.user_layout.vLine(2)
  252. self.user_layout.newLine()
  253. self.user_layout.addWidget(self.set_def_button)
  254. self.user_layout.addWidget(self.reset_button)
  255. # line3 = QtGui.QFrame()
  256. # line3.setFrameShape(QtGui.QFrame.HLine)
  257. # self.user_layout.addWidget(line3, newLine=True, colSpan=4)
  258. self.user_layout.hLine('full')
  259. self.user_layout.newLine()
  260. self.user_layout.addWidget(self.acquire_button)
  261. self.user_layout.addWidget(self.single_read_button)
  262. self.user_layout.addWidget(self.reinit_status_button)
  263. # line4 = QtGui.QFrame()
  264. # line4.setFrameShape(QtGui.QFrame.HLine)
  265. # self.user_layout.addWidget(line4, newLine=True, colSpan=4)
  266. self.user_layout.hLine('full')
  267. self.user_layout.newLine()
  268. self.user_layout.addWidget(self.get_image_type)
  269. self.user_layout.addWidget(self.get_image_adc_field)
  270. self.user_layout.addWidget(self.get_image_button)
  271. self.user_layout.newLine()
  272. self.user_layout.skipCol()
  273. self.user_layout.addWidget(self.get_placeholder)
  274. self.user_layout.addWidget(self.get_button)
  275. self.user_layout.newLine()
  276. self.user_layout.addWidget(self.set_key_placeholder_button)
  277. self.user_layout.addWidget(self.set_value_field)
  278. self.user_layout.addWidget(self.set_button)
  279. self.output = customTextEdit()
  280. self.output.setReadOnly(True)
  281. self.layout.addWidget(self.output)
  282. self.image = QtGui.QLabel()
  283. self.image.hide()
  284. # self.layout.addWidget(self.image)
  285. def send(self, command):
  286. bk = self.parent().statusText.text()
  287. self.parent().statusText.setText("Working...")
  288. QtGui.QApplication.processEvents()
  289. r = client.send(command, self.host, self.port, p=False).strip()
  290. self.parent().statusText.setText(bk)
  291. return r
  292. def conn(self):
  293. try:
  294. host = self.host_edit.text()
  295. port = int(self.port_edit.text())
  296. client.send('get status', host, port, p=False)
  297. self.host = host
  298. self.port = port
  299. for button in self.buttons:
  300. button.setEnabled(True)
  301. self.parent().statusText.setText("Connected")
  302. self.load_keys()
  303. except:
  304. self.output.append("Connection Error")
  305. def load_keys(self):
  306. r = self.send('get possible_keys')
  307. idx1 = self.user_layout.getItemPosition(self.user_layout.indexOf(self.set_key_placeholder_button))
  308. idx2 = self.user_layout.getItemPosition(self.user_layout.indexOf(self.get_placeholder))
  309. self.user_layout.removeWidget(self.set_key_placeholder_button)
  310. self.user_layout.removeWidget(self.get_placeholder)
  311. self.set_key_placeholder_button.hide()
  312. self.get_placeholder.hide()
  313. self.set_key_field = QtGui.QComboBox()
  314. self.get_field = QtGui.QComboBox()
  315. self.get_field.addItem('all_acquisition')
  316. self.set_key_field.addItems(r.split('\n'))
  317. self.get_field.addItems(r.split('\n'))
  318. self.user_layout.addWidget(self.set_key_field, line=idx1[0], col=idx1[1])
  319. self.user_layout.addWidget(self.get_field, line=idx2[0], col=idx2[1])
  320. syntax = r.split('\n')
  321. syntax.extend(["Orbits Observed", "Orbits Skipped", "Count", "Wait Time", "Pilot Bunch Simulator", "Header"])
  322. self.output.setKeywords(syntax)
  323. def cal(self):
  324. r = self.send('calibrate')
  325. self.output.append(r)
  326. def sync(self):
  327. r = self.send('sync')
  328. self.output.append(r)
  329. def set_def(self):
  330. r = self.send('set_defaults')
  331. self.output.append(r)
  332. def reset(self):
  333. r = self.send('reset')
  334. self.output.append(r)
  335. def acq(self):
  336. r = self.send('acquire')
  337. self.output.append(r)
  338. if 'started' in r:
  339. self.parent().statusbar.addWidget(self.progressbar)
  340. self.progressbar.show()
  341. self.status()
  342. else:
  343. self.parent().statusbar.removeWidget(self.progressbar)
  344. self.progressbar.hide()
  345. def status(self):
  346. r = self.send('get status')
  347. if 'No' in r:
  348. self.parent().statusbar.removeWidget(self.progressbar)
  349. self.progressbar.hide()
  350. self.output.append(r)
  351. else:
  352. if not self.progressbar in self.parent().statusbar.children():
  353. self.parent().statusbar.addWidget(self.progressbar)
  354. self.progressbar.show()
  355. r = int(r.strip("%"))
  356. self.progressbar.setValue(r)
  357. timer = QtCore.QTimer()
  358. timer.singleShot(1000, self.status)
  359. def set(self):
  360. r = self.send('set ' + str(self.set_key_field.currentText()) + " " + str(self.set_value_field.text()))
  361. self.output.append(r)
  362. def get(self):
  363. r = self.send('get ' + str(self.get_field.currentText()))
  364. self.output.append(r)
  365. def get_image(self):
  366. self.send('get_image '+str(self.get_image_type.currentText()) + ' ' + str(self.get_image_adc_field.value()))
  367. pixmap = QtGui.QPixmap('/tmp/kcgimage.png')
  368. self.image.setPixmap(pixmap.scaledToHeight(700, mode=QtCore.Qt.SmoothTransformation))
  369. # self.image.setPixmap(pixmap)
  370. self.image.setMinimumSize(self.image.pixmap().size())
  371. self.image.show()
  372. def single_read(self):
  373. r = self.send("singleread")
  374. self.output.append(r)
  375. app = QtGui.QApplication([])
  376. rem = KCGRemote()
  377. rem.show()
  378. app.exec_()