Browse Source

max_freq:mode switch, table:copy text, AFset,blockcounts updated fewer, text background: black-> default, ?ord(char)? for unknown symbols,arg-diff decoder (better if signal bad)

master
Clemens Richter 9 years ago
parent
commit
e993c192e9
  1. 2
      grc/crfa_rds_parser_table_qt.xml
  2. 65
      python/max_freq.py
  3. 172
      python/rds_parser_table_qt.py

2
grc/crfa_rds_parser_table_qt.xml

@ -82,7 +82,7 @@ $(gui_hint()($win))</make>
<name>in</name> <name>in</name>
<type>message</type> <type>message</type>
<nports>$nPorts</nports> <nports>$nPorts</nports>
<!--<optional>1</optional>--> <!-- <optional>1</optional> -->
</sink> </sink>
<sink> <sink>
<name>freq</name> <name>freq</name>

65
python/max_freq.py

@ -43,9 +43,13 @@ class max_freq(gr.sync_block):
self.counter=0 self.counter=0
self.message_port_register_in(pmt.intern('ctrl')) self.message_port_register_in(pmt.intern('ctrl'))
self.set_msg_handler(pmt.intern('ctrl'), self.handle_ctrl_msg) self.set_msg_handler(pmt.intern('ctrl'), self.handle_ctrl_msg)
self.searchMode=True
def handle_ctrl_msg(self,msg): def handle_ctrl_msg(self,msg):
m = pmt.pmt_to_python.pmt_to_dict(msg) m = pmt.pmt_to_python.pmt_to_dict(msg)
print(m) #print(m)
if m.has_key("cmd") and m["cmd"]=="switch mode":
self.searchMode=not self.searchMode
print("searchMode: %s"%self.searchMode)
def set_center_freq(self, freq=None): def set_center_freq(self, freq=None):
if freq is not None: if freq is not None:
if isinstance(freq, float) or isinstance(freq, int): if isinstance(freq, float) or isinstance(freq, int):
@ -56,7 +60,7 @@ class max_freq(gr.sync_block):
if self.counter<5: if self.counter<5:
self.counter+=1 self.counter+=1
return len(input_items[0]) return len(input_items[0])
else: elif self.searchMode:
self.counter=0 self.counter=0
#in0 = input_items[0] #in0 = input_items[0]
#ii=input_items #ii=input_items
@ -110,60 +114,6 @@ class max_freq(gr.sync_block):
station_indices_trunc=list(station_indices_sorted)#copy list station_indices_trunc=list(station_indices_sorted)#copy list
del station_indices_trunc[self.num_decoders:]#remove non decodable incidices del station_indices_trunc[self.num_decoders:]#remove non decodable incidices
###############################
#comparelist=[]
#for freq in station_indices_trunc:
#comparelist.append({"freq":freq,"decoder":None,"new":True})#new detected-> no assigned decoder
#for decnum,freq in enumerate(self.last_station_indices):
#comparelist.append({"freq":freq,"decoder":decnum,"new":False})
##comparelist.sort()
#comparelist_sorted=sorted(comparelist, key=lambda k: k['freq'])
#print(comparelist_sorted)
#differences=[]
#station_indices_tune=[0]*4#TODO what if < 4 max freqs?
#last_elem=None
#same_station_threshold=2
#new_freqs=[]
##for elem in comparelist_sorted:
#while len(comparelist_sorted)>0:
#elem=comparelist_sorted.pop(0)#get and remove first
#freq=elem["freq"]
#if not last_elem==None and not elem["freq"]==0:
#fdiff=abs(freq-last_elem["freq"])
#differences.append(fdiff)
#if fdiff<same_station_threshold:#freq approx same-> use old decoder
#if elem["new"]:#if elem is new last_elem must be old
#decnum=last_elem["decoder"]
#freq=elem["freq"]#use new freq
#else:
#decnum=elem["decoder"]
#freq=last_elem["freq"]#use new freq
#station_indices_tune[decnum]=freq
#else:#stations different -> save last_elem and compare with next
#if last_elem["new"]:#save new
#new_freqs.append(last_elem["freq"])
#last_elem=elem
#if last_elem["new"]:#save new
#new_freqs.append(last_elem["freq"])
#station_indices_tune=list(set(station_indices_tune))#remove duplicates
#for i,freq in enumerate(station_indices_tune):
#if freq==0 and len(new_freqs)>0:#decoder unused
#station_indices_tune[i]=new_freqs.pop()#assign new freq
#print("diff %s"%differences)
#print("tune:%s"%station_indices_tune)
#print("nomatch:%s"%new_freqs)
###############################
#problems:
#very slow, sometimes switches
###############################
#station_indices_tune.sort()
###############################
#problems: swtiching
station_indices_tune=[0]*self.num_decoders station_indices_tune=[0]*self.num_decoders
same_station_threshold=3 same_station_threshold=3
new_stations=[] new_stations=[]
@ -192,6 +142,7 @@ class max_freq(gr.sync_block):
for index in station_indices_tune: for index in station_indices_tune:
startfreq=self.center_freq-self.samp_rate/2 startfreq=self.center_freq-self.samp_rate/2
freq=self.samp_rate*index/self.fft_len+startfreq freq=self.samp_rate*index/self.fft_len+startfreq
freq+=30000#add 30k because detected max often too low
num_decimals=int(round(math.log(self.snapto,10))) num_decimals=int(round(math.log(self.snapto,10)))
station_freqs.append(round(freq,-num_decimals)) station_freqs.append(round(freq,-num_decimals))
station_strength.append(round(numbers[index],-2)) station_strength.append(round(numbers[index],-2))
@ -207,4 +158,6 @@ class max_freq(gr.sync_block):
print(station_freqs) print(station_freqs)
return len(input_items[0]) return len(input_items[0])
else:
return len(input_items[0])

172
python/rds_parser_table_qt.py

@ -21,15 +21,15 @@
from __future__ import print_function#print without newline print('.', end="") from __future__ import print_function#print without newline print('.', end="")
import numpy import numpy
from gnuradio import gr from gnuradio import gr
import pmt,functools,csv,md5,collections,copy,sqlite3,atexit,time,folium import pmt,functools,csv,md5,collections,copy,sqlite3,atexit,time,re,folium
from datetime import datetime from datetime import datetime
import crfa.chart as chart import crfa.chart as chart
from PyQt4 import Qt, QtCore, QtGui from PyQt4 import Qt, QtCore, QtGui
import pprint,code,pickle#for easier testing import pprint,code,pickle#for easier testing
pp = pprint.PrettyPrinter() pp = pprint.PrettyPrinter()
import cProfile, pstats, StringIO #for profiling #import cProfile, pstats, StringIO #for profiling
pr = cProfile.Profile() #pr = cProfile.Profile()#disabled-internal-profiling
#from threading import Timer#to periodically save DB #from threading import Timer#to periodically save DB
@ -264,11 +264,11 @@ class tmc_message:
if self.count==gsi: #group in sequence if self.count==gsi: #group in sequence
data1=int(tmc_y&0xfff)#data block 1 data1=int(tmc_y&0xfff)#data block 1
data2=int(tmc_z)#data block 2 data2=int(tmc_z)#data block 2
#code.interact(local=locals())
self.data_arr.append("0x%03X"%data1)#3 hex characters self.data_arr.append("0x%03X"%data1)#3 hex characters
self.data_arr.append("0x%04X"%data2)#4 hex characters self.data_arr.append("0x%04X"%data2)#4 hex characters
#print(gsi) #print(gsi)
#code.interact(local=locals())
if self.count==0:#last group if self.count==0:#last group
self.is_complete=True self.is_complete=True
self.debug_data=copy.deepcopy(self.data_arr) self.debug_data=copy.deepcopy(self.data_arr)
@ -567,7 +567,7 @@ class rds_parser_table_qt(gr.sync_block):
self.RDS_data[PI]["AID_list"]={} self.RDS_data[PI]["AID_list"]={}
self.RDS_data[PI]["PSN"]="_"*8 self.RDS_data[PI]["PSN"]="_"*8
self.RDS_data[PI]["PSN_valid"]=[False]*8 self.RDS_data[PI]["PSN_valid"]=[False]*8
self.RDS_data[PI]["AF"]={} self.RDS_data[PI]["AF"]={"set":set(),"rxset":set()}
self.RDS_data[PI]["TP"]=-1 self.RDS_data[PI]["TP"]=-1
self.RDS_data[PI]["TA"]=-1 self.RDS_data[PI]["TA"]=-1
self.RDS_data[PI]["PTY"]="" self.RDS_data[PI]["PTY"]=""
@ -577,8 +577,10 @@ class rds_parser_table_qt(gr.sync_block):
if time.time()-self.save_data_timer > 10:#every 10 seconds if time.time()-self.save_data_timer > 10:#every 10 seconds
self.save_data_timer=time.time() self.save_data_timer=time.time()
self.clean_data_and_commit_db() self.clean_data_and_commit_db()
pr.enable() #pr.enable()#disabled-internal-profiling
#code.interact(local=locals()) #db=sqlite3.connect(self.db_name)
db=self.db
array=pmt.to_python(msg)[1] array=pmt.to_python(msg)[1]
groupNR=array[2]&0b11110000 groupNR=array[2]&0b11110000
groupVar=array[2]&0b00001000 groupVar=array[2]&0b00001000
@ -613,9 +615,15 @@ class rds_parser_table_qt(gr.sync_block):
freq_str="%i:%0.1fM"% (port,freq/1e6) freq_str="%i:%0.1fM"% (port,freq/1e6)
self.RDS_data[PI]["tuned_freq"]=freq self.RDS_data[PI]["tuned_freq"]=freq
#self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str}) #self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str})
if self.RDS_data[PI]["blockcounts"].has_key(groupType):
self.RDS_data[PI]["blockcounts"][groupType] +=1 #increment
else:
self.RDS_data[PI]["blockcounts"][groupType] = 1 #initialize (1st group of this type)
self.RDS_data[PI]["blockcounts"]["any"]+=1 self.RDS_data[PI]["blockcounts"]["any"]+=1
if self.RDS_data[PI]["blockcounts"]["any"]==5: if self.RDS_data[PI]["blockcounts"]["any"]==5:
self.RDS_data[PI]["blockcounts"]["any"]=0 self.RDS_data[PI]["blockcounts"]["any"]=0
t=(str(PI),groupType,self.RDS_data[PI]["blockcounts"][groupType])#TODO only update DB every few seconds
db.execute("INSERT OR REPLACE INTO grouptypeCounts (PI,grouptype,count) VALUES (?,?,?)",t)
dots="."*self.RDS_data[PI]["blockcounts"]["any"] dots="."*self.RDS_data[PI]["blockcounts"]["any"]
self.RDS_data[PI]["TP"]=TP self.RDS_data[PI]["TP"]=TP
self.RDS_data[PI]["PTY"]=self.pty_dict[PTY] self.RDS_data[PI]["PTY"]=self.pty_dict[PTY]
@ -623,22 +631,15 @@ class rds_parser_table_qt(gr.sync_block):
#save block to sqlite (commit at end of handle_msg) #save block to sqlite (commit at end of handle_msg)
#(time text,PI text,PSN text, grouptype text,content blob) #(time text,PI text,PSN text, grouptype text,content blob)
content="%02X%02X%02X%02X%02X" %(array[3]&0x1f,array[4],array[5],array[6],array[7]) content="%02X%02X%02X%02X%02X" %(array[3]&0x1f,array[4],array[5],array[6],array[7])
#db=sqlite3.connect(self.db_name)
db=self.db
#t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],groupType,content) #t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],groupType,content)
#db.execute("INSERT INTO groups VALUES (?,?,?,?,?)",t) #db.execute("INSERT INTO groups VALUES (?,?,?,?,?)",t)
if self.RDS_data[PI]["blockcounts"].has_key(groupType):
self.RDS_data[PI]["blockcounts"][groupType] +=1 #increment
else:
self.RDS_data[PI]["blockcounts"][groupType] = 1 #initialize (1st group of this type)
#error 161213: #error 161213:
# db.execute("INSERT OR REPLACE INTO grouptypeCounts (PI,grouptype,count) VALUES (?,?,?)",t) # db.execute("INSERT OR REPLACE INTO grouptypeCounts (PI,grouptype,count) VALUES (?,?,?)",t)
#InterfaceError: Error binding parameter 0 - probably unsupported type. #InterfaceError: Error binding parameter 0 - probably unsupported type.
#fix?: added str() to PI, but it should already be a string #fix?: added str() to PI, but it should already be a string
t=(str(PI),groupType,self.RDS_data[PI]["blockcounts"][groupType])#TODO only update DB every few seconds
db.execute("INSERT OR REPLACE INTO grouptypeCounts (PI,grouptype,count) VALUES (?,?,?)",t)
if (groupType == "0A"):#AF PSN if (groupType == "0A"):#AF PSN
adr=array[3]&0b00000011 adr=array[3]&0b00000011
segment=self.decode_chars(chr(array[6])+chr(array[7])) segment=self.decode_chars(chr(array[6])+chr(array[7]))
@ -677,13 +678,32 @@ class rds_parser_table_qt(gr.sync_block):
self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str}) self.signals.DataUpdateEvent.emit({'PI':PI,'freq':freq_str})
t=(PI,self.RDS_data[PI]["PSN"],float(freq),self.RDS_data[PI]["PTY"],int(self.RDS_data[PI]["TP"])) t=(PI,self.RDS_data[PI]["PSN"],float(freq),self.RDS_data[PI]["PTY"],int(self.RDS_data[PI]["TP"]))
db.execute("INSERT INTO stations (PI,PSN,freq,PTY,TP) VALUES (?,?,?,?,?)",t) db.execute("INSERT INTO stations (PI,PSN,freq,PTY,TP) VALUES (?,?,?,?,?)",t)
if self.RDS_data[PI].has_key("tuned_freq") :#TODO add secondary freqs
freq=self.decode_AF_freq(array[4])
diff=abs(freq-self.RDS_data[PI]["tuned_freq"])
if diff<100000:
self.RDS_data[PI]["AF"]["rxset"].add(freq)
freq=self.decode_AF_freq(array[5])
diff=abs(freq-self.RDS_data[PI]["tuned_freq"])
if diff<100000:
self.RDS_data[PI]["AF"]["rxset"].add(freq)
if(array[4]>= 224 and array[4]<= 249): if(array[4]>= 224 and array[4]<= 249):
#print("AF1 detected") #print("AF1 detected")
self.RDS_data[PI]["AF"]['number']=array[4]-224 self.RDS_data[PI]["AF"]['number']=array[4]-224
#self.RDS_data[PI]["AF"]['main']=self.decode_AF_freq(array[5]) #self.RDS_data[PI]["AF"]['main']=self.decode_AF_freq(array[5])
self.signals.DataUpdateEvent.emit({'row':port,'PI':PI,'AF':self.RDS_data[PI]["AF"]}) self.signals.DataUpdateEvent.emit({'row':port,'PI':PI,'AF':self.RDS_data[PI]["AF"]})
if(array[5]>= 224 and array[5]<= 249): if(array[5]>= 224 and array[5]<= 249):
print("AF2 detected (shouldn't happen)") print("AF2 detected (shouldn't happen) %s"%array[5])
#add frequencies to set
self.RDS_data[PI]["AF"]["set"].add(self.decode_AF_freq(array[4]))
self.RDS_data[PI]["AF"]["set"].add(self.decode_AF_freq(array[5]))
try:
self.RDS_data[PI]["AF"]["set"].remove(0)#remove control characters
except KeyError:
pass
name_list=list(self.RDS_data[PI]["PSN"]) name_list=list(self.RDS_data[PI]["PSN"])
if (name_list[adr*2:adr*2+2]==list(segment)):#segment already there if (name_list[adr*2:adr*2+2]==list(segment)):#segment already there
@ -706,7 +726,8 @@ class rds_parser_table_qt(gr.sync_block):
if (not self.RDS_data[PI]["PSN_valid"][i]): if (not self.RDS_data[PI]["PSN_valid"][i]):
valid = False valid = False
if(valid): if(valid):
textcolor="black" #textcolor="black"
textcolor=""#use default color (white if background is black)
if not self.RDS_data[PI]["internals"]["last_valid_psn"]==self.RDS_data[PI]["PSN"]:#ignore duplicates if not self.RDS_data[PI]["internals"]["last_valid_psn"]==self.RDS_data[PI]["PSN"]:#ignore duplicates
t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"PSN_valid",self.RDS_data[PI]["PSN"]) t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"PSN_valid",self.RDS_data[PI]["PSN"])
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t) db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
@ -800,7 +821,8 @@ class rds_parser_table_qt(gr.sync_block):
if (not self.RDS_data[PI]["RT_valid"][i]): if (not self.RDS_data[PI]["RT_valid"][i]):
self.RDS_data[PI]["RT_all_valid"] = False self.RDS_data[PI]["RT_all_valid"] = False
if(self.RDS_data[PI]["RT_all_valid"]): if(self.RDS_data[PI]["RT_all_valid"]):
textcolor="black" #textcolor="black"
textcolor=""#use default color (white if background is black)
l=list(self.RDS_data[PI]["RT"]) l=list(self.RDS_data[PI]["RT"])
rt="".join(l[0:text_end])#remove underscores(default symbol) after line end marker rt="".join(l[0:text_end])#remove underscores(default symbol) after line end marker
if not self.RDS_data[PI]["internals"]["last_valid_rt"]==rt:#ignore duplicates if not self.RDS_data[PI]["internals"]["last_valid_rt"]==rt:#ignore duplicates
@ -820,7 +842,7 @@ class rds_parser_table_qt(gr.sync_block):
rtcol=self.colorder.index('text') rtcol=self.colorder.index('text')
self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'string':formatted_text}) self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'string':formatted_text})
#code.interact(local=locals())
elif (groupType == "3A"):#ODA announcements (contain application ID "AID") elif (groupType == "3A"):#ODA announcements (contain application ID "AID")
AID=(array[6]<<8)|(array[7])#combine 2 bytes into 1 block AID=(array[6]<<8)|(array[7])#combine 2 bytes into 1 block
app_data=(array[4]<<8)|(array[5])#content defined by ODA-app app_data=(array[4]<<8)|(array[5])#content defined by ODA-app
@ -1038,6 +1060,7 @@ class rds_parser_table_qt(gr.sync_block):
if not self.RDS_data.has_key(PI_ON): if not self.RDS_data.has_key(PI_ON):
self.init_data_for_PI(PI_ON) self.init_data_for_PI(PI_ON)
self.RDS_data[PI_ON]["TP"]=TP_ON self.RDS_data[PI_ON]["TP"]=TP_ON
self.PI_dict[PI_ON]=0#initialize dict, even if no packets received
if self.log: if self.log:
print("found station %s via EON on station %s"%(PI_ON,PI)) print("found station %s via EON on station %s"%(PI_ON,PI))
if not self.RDS_data[PI]["EON"].has_key(PI_ON): if not self.RDS_data[PI]["EON"].has_key(PI_ON):
@ -1070,7 +1093,8 @@ class rds_parser_table_qt(gr.sync_block):
if (not self.RDS_data[PI_ON]["PSN_valid"][i]): if (not self.RDS_data[PI_ON]["PSN_valid"][i]):
valid = False valid = False
if(valid): if(valid):
textcolor="black" #textcolor="black"
textcolor=""#use default color (white if background is black)
else: else:
textcolor="gray" textcolor="gray"
@ -1121,7 +1145,7 @@ class rds_parser_table_qt(gr.sync_block):
printdelay=500 printdelay=500
self.printcounter+=0#printing disabled self.printcounter+=0#printing disabled
if self.printcounter == printdelay and self.debug: if self.printcounter == printdelay and self.debug:
#code.interact(local=locals())
for key in self.RDS_data: for key in self.RDS_data:
if self.RDS_data[key].has_key("PSN"): if self.RDS_data[key].has_key("PSN"):
psn=self.RDS_data[key]["PSN"] psn=self.RDS_data[key]["PSN"]
@ -1137,7 +1161,7 @@ class rds_parser_table_qt(gr.sync_block):
#db.commit() #db.commit()
#db.close() #db.close()
#pr.disable() #pr.disable() #disabled-internal-profiling
#end of handle_msg #end of handle_msg
def print_tmc_msg(self,tmc_msg): def print_tmc_msg(self,tmc_msg):
try: try:
@ -1174,13 +1198,13 @@ class rds_parser_table_qt(gr.sync_block):
marker_string=self.marker_template.format(lat=tmc_msg.location.ykoord,lon=tmc_msg.location.xkoord,text=map_tag)#without ID marker_string=self.marker_template.format(lat=tmc_msg.location.ykoord,lon=tmc_msg.location.xkoord,text=map_tag)#without ID
self.map_markers.append(marker_string) self.map_markers.append(marker_string)
#code.interact(local=locals())
except Exception as e: except Exception as e:
print(e) print(e)
raise raise
#print("line 1064") #print("line 1064")
#code.interact(local=locals())
except KeyError: except KeyError:
#print("location '%i' not found"%tmc_location) #print("location '%i' not found"%tmc_location)
pass pass
@ -1216,24 +1240,30 @@ class rds_parser_table_qt(gr.sync_block):
0b1001:u"âäêëîïôöûüñçş??ij", 0b1001:u"âäêëîïôöûüñçş??ij",
0b1100:u"ÁÀÉÈÍÌÓÒÚÙŘČŠŽĐĿ", 0b1100:u"ÁÀÉÈÍÌÓÒÚÙŘČŠŽĐĿ",
0b1101:u"ÂÄÊËÎÏÔÖÛÜřčšžđŀ"} 0b1101:u"ÂÄÊËÎÏÔÖÛÜřčšžđŀ"}
charlist=list(charstring) #charlist=list(charstring)
return_string=""
for i,char in enumerate(charstring): for i,char in enumerate(charstring):
#code.interact(local=locals())
if ord(char)<= 0b01111111: if ord(char)<= 0b01111111:
charlist[i]=char #use ascii #charlist[i]=char #use ascii
return_string+=char
else: else:
#split byte #split byte
alnr=(ord(char)&0xF0 )>>4 #upper 4 bit alnr=(ord(char)&0xF0 )>>4 #upper 4 bit
index=ord(char)&0x0F #lower 4 bit index=ord(char)&0x0F #lower 4 bit
#code.interact(local=locals())
try: try:
charlist[i]=alphabet[alnr][index] #charlist[i]=alphabet[alnr][index]
return_string+=alphabet[alnr][index]
except KeyError: except KeyError:
charlist[i]='?'#symbol not decoded #TODO return_string+="?%02X?"%ord(char)
#charlist[i]='?'#symbol not decoded #TODO
pass pass
return "".join(charlist) #return "".join(charlist)
return return_string
def color_text(self, text, start,end,textcolor,segmentcolor): def color_text(self, text, start,end,textcolor,segmentcolor):
formatted_text="<font face='Courier New' color='%s'>%s</font><font face='Courier New' color='%s'>%s</font><font face='Courier New' color='%s'>%s</font>"% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:]) #formatted_text="<font face='Courier New' color='%s'>%s</font><font face='Courier New' color='%s'>%s</font><font face='Courier New' color='%s'>%s</font>"% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:])
#formatted_text="<span style='background-color: yellow;color:%s'>%s</span><span style='color:%s'>%s</span><span style='color:%s'>%s</span>"% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:])
formatted_text=("<span style='font-family:Courier New;color:%s'>%s</span>"*3)% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:])
return formatted_text return formatted_text
class rds_parser_table_qt_Widget(QtGui.QWidget): class rds_parser_table_qt_Widget(QtGui.QWidget):
def __init__(self, signals,label,tableobj): def __init__(self, signals,label,tableobj):
@ -1244,59 +1274,25 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
""" Creates the QT Range widget """ """ Creates the QT Range widget """
QtGui.QWidget.__init__(self) QtGui.QWidget.__init__(self)
layout = Qt.QVBoxLayout() layout = Qt.QVBoxLayout()
self.label = Qt.QLabel(label) #self.label = Qt.QLabel(label)
layout.addWidget(self.label) #layout.addWidget(self.label)#title of table disabled to save space
#layout.addWidget(self.label)
self.setLayout(layout) self.setLayout(layout)
#self.decoder_to_PI={} #self.decoder_to_PI={}
self.PI_to_row={} self.PI_to_row={}
self.table=QtGui.QTableWidget(self) self.table=QtGui.QTableWidget(self)
rowcount=2 rowcount=0
self.table.setRowCount(rowcount) self.table.setRowCount(rowcount)
self.table.setColumnCount(9) self.table.setColumnCount(9)
self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) #disallow editing self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) #disallow editing
#Data
empty_text32='________________________________'
empty_text64='________________________________________________________________'
#empty_text64='\xe4'*64
self.data = {'ID':[ QtGui.QLabel() for i in range(rowcount)],
'freq':[ QtGui.QLabel() for i in range(rowcount)],
'name':[ QtGui.QLabel() for i in range(rowcount)],
'PTY':[ QtGui.QLabel() for i in range(rowcount)],
'AF':[ QtGui.QLabel() for i in range(rowcount)],
'time':[ QtGui.QLabel() for i in range(rowcount)],
'text':[ QtGui.QLabel("_"*64) for i in range(rowcount)],
'quality':[ QtGui.QLabel() for i in range(rowcount)],
'buttons':[]}
#Enter data onto Table
self.colorder=['ID','freq','name','PTY','AF','time','text','quality','buttons'] self.colorder=['ID','freq','name','PTY','AF','time','text','quality','buttons']
horHeaders = [] ##button.clicked.connect(self.getDetails)
for n, key in enumerate(self.colorder):
#for n, key in enumerate(sorted(self.data.keys())):
horHeaders.append(key)
for m, item in enumerate(self.data[key]):
if type(item)==int:#convert ints to strings
newitem = QtGui.QTableWidgetItem(str(item))
self.table.setItem(m, n, newitem)
elif isinstance(item,QtGui.QLabel):
self.table.setCellWidget(m,n,item)
else:
newitem = QtGui.QTableWidgetItem(item)
self.table.setItem(m, n, newitem)
for i in range(rowcount):#create buttons
button=QtGui.QPushButton("getDetails")
self.table.setCellWidget(i,self.table.columnCount()-1,button)
button.clicked.connect(functools.partial(self.getDetails, row=i))
#button.clicked.connect(self.getDetails)
#Add Header
layout.addWidget(self.label)
layout.addWidget(self.table)
self.table.setHorizontalHeaderLabels(horHeaders) layout.addWidget(self.table)
self.table.setHorizontalHeaderLabels(self.colorder)
#self.table.setMaximumHeight(300)#TODO use dynamic value #self.table.setMaximumHeight(300)#TODO use dynamic value
button_layout = Qt.QHBoxLayout() button_layout = Qt.QHBoxLayout()
codebutton = QtGui.QPushButton("code.interact") codebutton = QtGui.QPushButton("code.interact")
codebutton.clicked.connect(self.onCLick) codebutton.clicked.connect(self.onCLick)
@ -1337,6 +1333,22 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
font.setPointSize(10) font.setPointSize(10)
self.lastResizeTime=0 self.lastResizeTime=0
layout.addWidget(self.logOutput) layout.addWidget(self.logOutput)
self.clip = QtGui.QApplication.clipboard()
#self.cb.clear(mode=cb.Clipboard )
#self.cb.setText("Clipboard Text", mode=cb.Clipboard)
def keyPressEvent(self, e):
if (e.modifiers() & QtCore.Qt.ControlModifier):
selected = self.table.selectedRanges().pop()
selected.leftColumn()
selected.topRow()
if e.key() == QtCore.Qt.Key_C: #copy
try:
qs = self.table.cellWidget(selected.topRow(),selected.leftColumn()).text()#get QString from table
s=re.sub("<.*?>","", str(qs))#remove html tags
self.clip.setText(s)
except Exception as e:
print(e)
print("no text, cant copy")
def insert_empty_row(self): def insert_empty_row(self):
rowPosition = self.table.rowCount() rowPosition = self.table.rowCount()
self.table.insertRow(rowPosition) self.table.insertRow(rowPosition)
@ -1441,7 +1453,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
layout=Qt.QVBoxLayout() layout=Qt.QVBoxLayout()
layout.addWidget(l) layout.addWidget(l)
view.setLayout(layout) view.setLayout(layout)
#code.interact(local=locals())
view.exec_() view.exec_()
def getDetails(self,row): def getDetails(self,row):
PIcol=self.colorder.index('ID') PIcol=self.colorder.index('ID')
@ -1474,7 +1486,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
l.setWordWrap(True) l.setWordWrap(True)
#l=QtGui.QLabel("Data:") #l=QtGui.QLabel("Data:")
view.layout().addWidget(l) view.layout().addWidget(l)
#code.interact(local=locals())
view.exec_() view.exec_()
def onCLick(self): def onCLick(self):
print("button clicked") print("button clicked")
@ -1483,18 +1495,14 @@ if __name__ == "__main__":
from PyQt4 import Qt from PyQt4 import Qt
import sys import sys
# def valueChanged(frequency):
# print("Value updated - " + str(frequency))
app = Qt.QApplication(sys.argv) app = Qt.QApplication(sys.argv)
# widget = RangeWidget(Range(0, 100, 10, 1, 100), valueChanged, "Test", "counter_slider", int)
mainobj= rds_parser_table_qt_Signals() mainobj= rds_parser_table_qt_Signals()
#mainobj=None #mainobj=None
widget = rds_parser_table_qt_Widget(mainobj,"TestLabel") widget = rds_parser_table_qt_Widget(mainobj,"TestLabel")
widget.show() widget.show()
widget.setWindowTitle("Test Qt gui") widget.setWindowTitle("Test Qt gui")
widget.setGeometry(200,200,600,300) widget.setGeometry(200,200,600,300)
#code.interact(local=locals())
sys.exit(app.exec_()) sys.exit(app.exec_())
widget = None widget = None

Loading…
Cancel
Save