def addWidgets(self): layout = QVBoxLayout() self.setLayout(layout) layout.addSpacing(10) preamble = QLabel('This vault is locked.', self) layout.addWidget(preamble) passwdedt = QLineEdit(self) passwdedt.setPlaceholderText('Type password to unlock') passwdedt.setEchoMode(QLineEdit.Password) passwdedt.textChanged.connect(self.passwordChanged) passwdedt.returnPressed.connect(self.unlockVault) layout.addSpacing(10) layout.addWidget(passwdedt) self.passwdedt = passwdedt unlockcb = QCheckBox('Try unlock other vaults too', self) unlockcb.stateChanged.connect(self.saveConfig) unlockcb.setVisible(False) layout.addWidget(unlockcb) self.unlockcb = unlockcb status = QLabel('', self) status.setVisible(False) status.setContentsMargins(0, 10, 0, 0) layout.addWidget(status) self.status = status hbox = QHBoxLayout() unlockbtn = QPushButton('Unlock', self) unlockbtn.setFixedSize(unlockbtn.sizeHint()) unlockbtn.clicked.connect(self.unlockVault) unlockbtn.setEnabled(False) hbox.addWidget(unlockbtn) self.unlockbtn = unlockbtn hbox.addStretch(100) layout.addSpacing(10) layout.addLayout(hbox) layout.addStretch(100)
class ProgressDialog(QDialog): def __init__(self, title, description, parent): super(ProgressDialog, self).__init__(parent) self.setWindowTitle(title) self.label = QLabel(description, self) self.label.setContentsMargins(2, 0, 0, 0) self.progress = QProgressBar(self) self._createlayout() def _createlayout(self): l = QVBoxLayout() l.addWidget(self.label) l.addWidget(self.progress) self.setLayout(l)
def _createTrackProgress(self, parent, track): w = QWidget(parent) l = QVBoxLayout(w) p = QProgressBar(w) p.setRange(0, 100) p.setValue(track['progress']) w.progress = p label = QLabel(w) label.setContentsMargins(5, 2, 5, 2) label.setOpenExternalLinks(True) label.setWordWrap(True) if track['name'] is not None: label.setText(track['name']) elif track['error']: label.setText('<font color="red">%s</font>' % track['error']) p.setValue(100) w.label = label l.addWidget(label) l.addWidget(p) w.setLayout(l) return w
def setTickLabels(self, listWithLabels): lengthOfList = len(listWithLabels) for index, label in enumerate(listWithLabels): label = QLabel(str(label)) label.setContentsMargins(0, 0, 0, 0) if index > lengthOfList/3: label.setAlignment(QtCore.Qt.AlignCenter) if index > 2*lengthOfList/3: label.setAlignment(QtCore.Qt.AlignRight) self._labelTicksWidget.layout().addWidget(label)
def empty(self, with_accounts=None): if self.child: self.clear_layout(self) image = self.base.load_image("turpial-196.png", True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel("Turpial 3") if detect_os() == OS_MAC: font = QFont("Maven Pro Light", 28, 0, False) font2 = QFont("Ubuntu", 16, 0, False) else: font = QFont("Maven Pro Light", 18, QFont.Light, False) font2 = QFont("Ubuntu", 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get("welcome")) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() if with_accounts: text = "%s <a href='cmd:add_columns'>%s</a>" % ( i18n.get("you_have_accounts_registered"), i18n.get("add_some_columns"), ) else: text = "<a href='cmd:add_accounts'>%s</a> %s" % ( i18n.get("add_new_account"), i18n.get("to_start_using_turpial"), ) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.setSpacing(10) self.child.addWidget(message) self.child.setSpacing(10) self.child.setContentsMargins(30, 0, 30, 60) self.insertLayout(0, self.child) self.is_empty = True
def empty(self, with_accounts=None): if self.child: self.clear_layout(self) image = self.base.load_image('turpial-196.png', True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel('Turpial 3') if detect_os() == OS_MAC: font = QFont('Maven Pro Light', 28, 0, False) font2 = QFont('Ubuntu', 16, 0, False) else: font = QFont('Maven Pro Light', 18, QFont.Light, False) font2 = QFont('Ubuntu', 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get('welcome')) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() if with_accounts: text = "%s <a href='cmd:add_columns'>%s</a>" % (i18n.get( 'you_have_accounts_registered'), i18n.get('add_some_columns')) else: text = "<a href='cmd:add_accounts'>%s</a> %s" % (i18n.get( 'add_new_account'), i18n.get('to_start_using_turpial')) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.setSpacing(10) self.child.addWidget(message) self.child.setSpacing(10) self.child.setContentsMargins(30, 0, 30, 60) self.insertLayout(0, self.child) self.is_empty = True
def __init__(self, parent, description = "Please enter your login information:", loginText = "Login:"******"Password:"): QDialog.__init__(self, parent) self._username = None self._password = None formGridLayout = QGridLayout(self) descLabel = QLabel(description, self) descLabel.setWordWrap(True) descLabel.setContentsMargins(0,0,0,5) self.editUserName = QLineEdit(self) self.editPassword = QLineEdit(self) self.editPassword.setEchoMode( QLineEdit.Password ) labelUsername = QLabel(self) labelPassword = QLabel(self) labelUsername.setText(loginText) labelUsername.setBuddy(self.editUserName) labelPassword.setText(passwordText) labelPassword.setBuddy(self.editPassword) buttons = QDialogButtonBox(self) buttons.addButton(QDialogButtonBox.Ok) buttons.addButton(QDialogButtonBox.Cancel) buttons.button(QDialogButtonBox.Cancel).clicked.connect(self.close) buttons.button(QDialogButtonBox.Ok).clicked.connect(self.slotAcceptLogin) formGridLayout.addWidget(descLabel, 0, 0, 1, 2) formGridLayout.addWidget(labelUsername, 1, 0, 1, 1, Qt.AlignRight) formGridLayout.addWidget(self.editUserName, 1, 1) formGridLayout.addWidget(labelPassword, 2, 0, 1, 1, Qt.AlignRight) formGridLayout.addWidget(self.editPassword, 2, 1) formGridLayout.addWidget(buttons, 3, 0, 1, 2, Qt.AlignBottom) formGridLayout.setRowStretch(0, 0) formGridLayout.setRowStretch(1, 0) formGridLayout.setRowStretch(2, 0) formGridLayout.setRowStretch(3, 1) self.setMaximumHeight(self.sizeHint().height()) self.setMinimumHeight(self.sizeHint().height()) #self.setMinimumWidth(400) self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
def error(self): if self.child: self.clear_layout(self) image = self.base.load_image('turpial-196.png', True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel('Turpial 3') if detect_os() == OS_MAC: font = QFont('Maven Pro Light', 28, 0, False) font2 = QFont('Ubuntu', 16, 0, False) else: font = QFont('Maven Pro Light', 18, QFont.Light, False) font2 = QFont('Ubuntu', 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get('oh_oh')) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() text = "%s. <a href='cmd:restart'>%s</a>" % ( i18n.get('something_terrible_happened'), i18n.get('try_again')) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) #self.child.setSpacing(10) self.child.addStretch(1) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True
def loading(self): if self.child: self.clear_layout(self) image = self.base.load_image('turpial-196.png', True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel('Turpial 3') if detect_os() == OS_MAC: font = QFont('Maven Pro Light', 28, 0, False) font2 = QFont('Ubuntu', 16, 0, False) else: font = QFont('Maven Pro Light', 18, QFont.Light, False) font2 = QFont('Ubuntu', 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get('hi_there')) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() message.setText(i18n.get('give_me_a_minute')) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) loader = BarLoadIndicator() self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) #self.child.setSpacing(10) self.child.addStretch(1) self.child.addWidget(loader) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True
def loading(self): if self.child: self.clear_layout(self) image = self.base.load_image("turpial-196.png", True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel("Turpial 3") if detect_os() == OS_MAC: font = QFont("Maven Pro Light", 28, 0, False) font2 = QFont("Ubuntu", 16, 0, False) else: font = QFont("Maven Pro Light", 18, QFont.Light, False) font2 = QFont("Ubuntu", 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get("hi_there")) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() message.setText(i18n.get("give_me_a_minute")) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) loader = BarLoadIndicator() self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) # self.child.setSpacing(10) self.child.addStretch(1) self.child.addWidget(loader) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True
def error(self): if self.child: self.clear_layout(self) image = self.base.load_image("turpial-196.png", True) logo = QLabel() logo.setPixmap(image) logo.setAlignment(Qt.AlignCenter) logo.setContentsMargins(0, 80, 0, 0) appname = QLabel("Turpial 3") if detect_os() == OS_MAC: font = QFont("Maven Pro Light", 28, 0, False) font2 = QFont("Ubuntu", 16, 0, False) else: font = QFont("Maven Pro Light", 18, QFont.Light, False) font2 = QFont("Ubuntu", 12, QFont.Normal, False) appname.setFont(font) welcome = QLabel() welcome.setText(i18n.get("oh_oh")) welcome.setAlignment(Qt.AlignCenter) welcome.setFont(font) message = QLabel() text = "%s. <a href='cmd:restart'>%s</a>" % (i18n.get("something_terrible_happened"), i18n.get("try_again")) message.setText(text) message.linkActivated.connect(self.__link_clicked) message.setAlignment(Qt.AlignCenter) message.setWordWrap(True) message.setFont(font2) self.child = QVBoxLayout() self.child.addWidget(logo) self.child.addWidget(welcome) self.child.addSpacing(10) self.child.addWidget(message) # self.child.setSpacing(10) self.child.addStretch(1) self.child.setContentsMargins(30, 0, 30, 30) self.insertLayout(0, self.child) self.is_empty = True
class widget_pl_grid( QWidget ) : #----------------------------------------------------------------------- # DEFINE THE INITIALIZATION FUNCTION. #----------------------------------------------------------------------- def __init__( self, core, n, n_plt_x=None, n_plt_y=None, n_plt=None ) : # Inherit all attributes of an instance of "QWidget". super( widget_pl_grid, self ).__init__( ) # Initialize the counter of repaint events for this widget as # well as a maximum value for this counter. # Note. For some reason, adjusting the individual plots to have # uniform sizes is difficult to achieve before the widget # is rendered. Thus, once a paint event occurs, the # "self.paintEvent( )" function picks it up and makes a # call to "self.ajst_grd( )". This counter and its # maximum value are used ensure that "self.paintEvent( )" # makes such a call only in response to the intial few # painting (so as to prevent an infinite loop). # Note. The first paint seems to be a "dummy" of some sort. # Whatever the case, "self.n_paint_max = 1" seems to # generally be insufficient. self.n_painted = 0 self.n_painted_max = 3 # Disable user events self.setDisabled( True ) self.core = core self.n = n self.t = [] self.delta_t = [] self.time_label = QLabel( ' ' ) self.time_label.setAlignment( Qt.AlignCenter ) self.time_label.setContentsMargins( 0,5,0,0 ) font = QFont( ) font.setBold(True) self.time_label.setFont( font ) # Prepare to respond to signals received from the Janus core. self.connect( self.core, SIGNAL('janus_rset'), self.resp_rset ) self.connect( self.core, SIGNAL('janus_chng_pl_spc'), self.resp_chng_pl_spc ) self.connect( self.core, SIGNAL('janus_chng_mom_pl_sel'), self.resp_chng_mom_pl_sel ) self.connect( self.core, SIGNAL('janus_chng_mom_pl_res'), self.resp_chng_mom_pl_res ) self.connect( self.core, SIGNAL('janus_chng_nln_gss'), self.resp_chng_nln_gss ) self.connect( self.core, SIGNAL('janus_chng_nln_sel_all'), self.resp_chng_nln_sel_all ) self.connect( self.core, SIGNAL('janus_chng_nln_res'), self.resp_chng_nln_res ) self.connect( self.core, SIGNAL('janus_chng_dsp'), self.resp_chng_dsp ) #TODO add more signals # Assign (if not done so already) and store the shape of the # plot-grid array. self.n_plt_x = 5 if ( n_plt_x is None ) else n_plt_x self.n_plt_y = 5 if ( n_plt_y is None ) else n_plt_y if ( n_plt is None ) : self.n_plt = self.n_plt_x * self.n_plt_y # Initizalize the pens, brushes, and fonts used by this widget. self.pen_plt = mkPen( color='k' ) self.pen_hst = mkPen( color='k' ) self.pen_pnt_c = mkPen( color='k' ) self.pen_pnt_y = mkPen( color='k' ) self.pen_pnt_r = mkPen( color='k' ) self.pen_crv_b = mkPen( color='b' ) self.pen_crv_g = mkPen( color='g' ) self.bsh_pnt_c = mkBrush( color='c' ) self.bsh_pnt_y = mkBrush( color='y' ) self.bsh_pnt_r = mkBrush( color='r' ) self.fnt = self.core.app.font( ) # Set the maximum number of velocity channels and the maximum # number of ion species. self.n_k = 14 self.n_ion = self.core.nln_n_pop # Initialize the widget and it's plot's. self.init_plt( ) # Populate the plots with the histograms (and labels), the # selection points, and the fit curves. self.make_hst( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR INITIALIZING THE WIDGET AND ITS PLOTS. #----------------------------------------------------------------------- def init_plt( self ) : # Initialize the "GraphicsLayoutWidget" for this widget. This # will allow a grid of "GraphicsItem" objects, which will # include the plots themselves, the axes, and the axis labels. # Note. The "QGridLayout" object given to this widget as its # layout is essentially a dummy. I tried to just having # this widget be an extention of "GraphicsLayoutWidget" # (i.e., having it inheret that type), but I couldn't get # it to display anything at all. self.setLayout( QGridLayout( ) ) self.grd = GraphicsLayoutWidget( ) self.grd.setBackground( 'w' ) self.layout( ).addWidget( self.time_label ) self.layout( ).addWidget( self.grd ) self.layout().setContentsMargins( 0, 0, 0, 0 ) # Initialize the text for the x- and y-axis labels. Then, # create the labels themselves and add them to the grid. self.txt_axs_x = 'Projected Proton Inflow Velocity [km/s]' self.txt_axs_y = 'Phase-space Density' +\ u'[cm\u00AF\u00B3/(km/s)\u00B3]' if ( self.core.app.res_lo ) : size = '8pt' else : size = '10pt' self.lab_axs_x = LabelItem( self.txt_axs_x, angle=0 , color='b', size=size ) self.lab_axs_y = LabelItem( self.txt_axs_y, angle=270, color='b', size=size ) self.grd.addItem( self.lab_axs_x, self.n_plt_y + 1, 2, 1, self.n_plt_x ) self.grd.addItem( self.lab_axs_y, 0, 0, self.n_plt_y, 1 ) # Initialize the arrays that will contain the individual axes, # plots, and plot elements (i.e., the histograms, fit curves, # labels, and selection points). self.plt = tile( None, [ self.n_plt_y, self.n_plt_x ] ) self.axs_x = tile( None, self.n_plt_x ) self.axs_y = tile( None, self.n_plt_y ) self.hst = tile( None, [ self.n_plt_y, self.n_plt_x ] ) self.lbl = tile( None, [ self.n_plt_y, self.n_plt_x ] ) self.crv = tile( None, [ self.n_plt_y, self.n_plt_x ] ) self.crv_ion = tile( None, [ self.n_plt_y, self.n_plt_x, self.n_ion ] ) self.pnt = tile( None, [ self.n_plt_y, self.n_plt_x, self.n_k ] ) # Initialize the scale-type for each axis, then generate the # (default) axis-limits and adjusted axis-limits. self.log_x = False self.log_y = True self.make_lim( ) # Create, store, and add to the grid the individual axes: first # the horizontal and then the vertical. for i in range( self.n_plt_x ) : self.axs_x[i] = AxisItem( 'bottom', maxTickLength=5 ) self.axs_x[i].setLogMode( self.log_x ) self.axs_x[i].setRange( self.x_lim[0], self.x_lim[1] ) self.axs_x[i].setTickFont( self.fnt ) if ( self.core.app.res_lo ) : self.axs_x[i].setHeight( 10 ) else : self.axs_x[i].setHeight( 20 ) self.grd.addItem( self.axs_x[i], self.n_plt_y, i + 2 ) for j in range( self.n_plt_y ) : self.axs_y[j] = AxisItem( 'left', maxTickLength=5 ) self.axs_y[j].setLogMode( self.log_y ) self.axs_y[j].setRange( self.y_lim[0], self.y_lim[1] ) self.axs_y[j].setTickFont( self.fnt ) if ( self.core.app.res_lo ) : self.axs_y[j].setWidth( 32 ) else : self.axs_y[j].setWidth( 40 ) self.grd.addItem( self.axs_y[j], j, 1 ) # Create, store, and add to the grid the individual plots. # Likewise, create, store, and add to each plot a label. for t in range( self.n_plt_y ) : for p in range( self.n_plt_x ) : # Compute the plot number of this plot. d = p + ( t * self.n_plt_x ) # If creating this plot would exceed the # specified number of plots, don't create it. if ( d >= self.n_plt ) : continue # Create and store this plot, adjust its limits, # and add it to the grid. # Note: locations of plots are inverted along # theta self.plt[t,p] = event_ViewBox( self, border=self.pen_plt, enableMouse=False, enableMenu=False ) self.plt[t,p].setRange( xRange=self.x_lim, yRange=self.y_lim, padding=0. ) self.grd.addItem( self.plt[t,p], self.n_plt_y-t-1, p + 2 ) # Create and store an (empty) label and add it # to this plot. self.lbl[t,p] = TextItem( anchor=(1,0) ) self.lbl[t,p].setFont( self.fnt ) self.plt[t,p].addItem( self.lbl[t,p] ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR GENERATING AXIS-LIMITS (AND ADJUSTED LIMITS). #----------------------------------------------------------------------- def make_lim( self ) : # If no spectrum has been loaded, use the default limits; # otherwise, use the spectral data to compute axis limits. # Note: velocities are recorded in reverse order. if ( self.core.pl_spec_arr == [] ) : self.domain = [ 300. , 900. ] self.range = [ 1.e-10, 1.e-5 ] else : self.domain = [self.core.pl_spec_arr[self.n]['vel_strt'][0], self.core.pl_spec_arr[self.n]['vel_stop'][-1]] arr_psd_flat = [self.core.pl_spec_arr[self.n]['psd_flat'][i] for i in (where(array(self.core.pl_spec_arr[self.n]['psd_flat']) != 0.)[0])] self.range = [ self.core.mom_psd_min, self.core.mom_psd_max ] # Note: psd values are less than 1 if ( self.log_y ) : self.range[0] = self.range[0] ** 1.05 self.range[1] = self.range[1] ** 0.9 else : self.range[1] += 0.1 * ( self.range[1] - self.range[0] ) # Compute the "adjusted limits" for each axis. if ( self.log_x ) : self.x_lim = [ log10( x ) for x in self.domain ] else : self.x_lim = self.domain if ( self.log_y ) : self.y_lim = [ log10( y ) for y in self.range ] else : self.y_lim = self.range #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR CREATING THE PLOTS' HISTOGRAMS (AND LABELS). #----------------------------------------------------------------------- def make_hst( self ) : # Reset the timestamp label self.time_label.setText( ' ' ) # If no spectrum has been loaded, abort. if ( self.core.pl_spec_arr == [] ) : return # If the index of this P-L grid is outside the bounds of the P-L # spectrum currently loaded, abort. if ( self.n >= len( self.core.pl_spec_arr ) ) : return # Generate the timestamp label self.t = self.t + [self.core.pl_spec_arr[self.n]['time'][0]] self.t_0 = self.core.fc_spec['time'] self.delta_t = self.delta_t + [( self.t[-1]- self.t_0 ).total_seconds( )] self.time_label.setText( str(self.t[-1])[0:-7] + ' ' + u'\u0394t = {}'.format( round( self.delta_t[-1], 0) ) + 's' ) # Use the spectral data to compute new axis-limits. self.make_lim( ) for p in range( self.n_plt_x ) : self.axs_x[p].setRange( self.x_lim[0], self.x_lim[1] ) for t in range( self.n_plt_y ) : self.axs_y[t].setRange( self.y_lim[0], self.y_lim[1] ) # Histograms are broken down by phi horizontally and # theta vertically for t in range( self.core.pl_spec_arr[self.n]['n_the'] ): for p in range ( self.core.pl_spec_arr[self.n]['n_phi'] ): # If this plot does not exist, move onto # the next one. if ( self.plt[t,p] is None ) : continue #-----------------------------# #---DATA GENERATION SECTION---# #-----------------------------# # Generate a step function for the # look direction associated with this widget. self.stp = array( [step( self.core.pl_spec_arr[self.n]['vel_cen'], self.core.pl_spec_arr[self.n]['vel_del'], self.core.pl_spec_arr[self.n]['psd'][t][p])]) # Calculate the points to be plotted from the # step function stp_pnt = array( [ array( datum.calc_pnt( lev_min=self.range[0]/2.) ) for datum in self.stp ] ) self.x_set = stp_pnt[:,0][0] self.y_set = stp_pnt[:,1][0] # If plotting log(y) and there are any psd # values of zero, replace those points with an # arbitrary minimum y value if ( self.log_y ) : y_min = self.range[0]/2. self.y_lim[0] = log10(y_min) self.y_set = [ max( y, y_min ) for y in self.y_set ] # If generating a log plot, take the log of the # points to be plotted self.x_pnts = log10( self.x_set ) if ( self.log_x ) else \ self.x_set self.y_pnts = log10( self.y_set ) if ( self.log_y ) else \ self.y_set #---------------------------------# #---GRAPHICS GENERATION SECTION---# #---------------------------------# # If a histogram already exists for this plot, # remove and delete it. if ( self.hst[t,p] is not None ) : self.plt[t,p].removeItem(self.hst[t,p]) self.hst[t,p] = None # Clear this plot's label of text. self.lbl[t,p].setText( '' ) # Adjust this plot's limits and then move it's # label in response. self.plt[t,p].setRange( xRange=self.x_lim, yRange=self.y_lim, padding=0. ) self.lbl[t,p].setPos( self.x_lim[1], self.y_lim[1] ) # Update this plot's label with appropriate text # indicating the pointing direction. elev = round( self.core.pl_spec_arr[self.n]['elev_cen'][t] ) azim = round( self.core.pl_spec_arr[self.n]['azim_cen'][p] ) txt = ( u'({0:+.0f}\N{DEGREE SIGN}, ' + u'{1:+.0f}\N{DEGREE SIGN})' ).format( elev, azim-180 ) self.lbl[t,p].setText( txt, color=(0,0,0) ) # Generate the histogram for the data from this # look direction and display it in the plot. self.hst[t,p] = PlotDataItem( self.x_pnts, self.y_pnts, pen=self.pen_hst ) self.plt[t,p].addItem( self.hst[t,p] ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR CREATING THE PLOTS' SELECTION POINTS. #----------------------------------------------------------------------- def make_pnt( self ) : # If no spectrum has been loaded, abort. if ( self.core.pl_spec_arr == [] ) : return # If the index of this P-L grid is outside the bounds of the P-L # spectrum currently loaded, abort. if ( self.n >= len( self.core.pl_spec_arr ) ) : return # Add selection points to each plot. for d in range( min( self.core.pl_spec_arr[self.n]['n_dir'], self.n_plt ) ) : # Determine the location of this plot within the grid # layout. t = d // self.n_plt_x p = d % self.n_plt_y # If this plot does not exist, move onto the next one. if ( self.plt[t,p] is None ) : continue # Add the selection points to this plot. for b in range( self.core.pl_spec_arr[self.n]['n_bin'] ) : sel_bin = False sel_dir = True sel_alt = None if( self.core.dsp == 'mom' ): sel_bin = self.core.pl_spec_arr[self.n].arr[t][p][b]['mom_sel'] elif ( ( self.core.dsp == 'gsl' or self.core.dsp == 'nln' ) and ( self.core.nln_pl_sel is not None ) ) : sel_bin = self.core.nln_pl_sel[self.n][t][p][b] # elif ( ( self.core.dsp == 'nln' ) and # ( self.core.pl_spec_arr[self.n].nln_res_sel # is not None ) ) : # sel_bin = \ # self.core.nln_pl_sel[t][p][b] # if ( self.core.pl_spec_arr[self.n].nln_sel is None ) : # sel_alt = None # else : # sel_alt = \ # self.core.pl_spec_arr[self.n].nln_sel[t][p][b] self.chng_pnt( t, p, b, sel_bin, sel_alt=sel_alt ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR CHANGING THE VISIBILITY OF A DATUM'S POINTS. #----------------------------------------------------------------------- def chng_pnt( self, t, p, b, sel_bin, sel_alt=None ) : # If no spectrum has been loaded, abort. if ( self.core.pl_spec_arr == [] ) : return # If the index of this P-L grid is outside the bounds of the P-L # spectrum currently loaded, abort. if ( self.n >= len( self.core.pl_spec_arr ) ) : return # If this point already exists, remove it from its plot and # delete it. if ( self.pnt[t,p,b] is not None ) : self.plt[t,p].removeItem( self.pnt[t,p,b] ) self.pnt[t,p,b] = None # If this point was not selected (based on both its primary and # secondary states), return (since there's nothing more to be # done). if ( not sel_bin or self.core.pl_spec_arr[self.n]['psd'][t][p][b] == 0) : return # Determine the "d" index corresponding to this look direction. d = p + ( t * self.n_plt_x ) # Computed the adjusted point location in the "ViewBox". if ( self.log_x ) : ax = log10( self.core.pl_spec_arr[self.n]['vel_cen'][b] ) else : ax = self.core.pl_spec_arr[self.n]['vel_cen'][b] if ( self.log_y ) : ay = log10( self.core.pl_spec_arr[self.n]['psd'][t][p][b] ) else : ay = self.core.pl_spec_arr[self.n]['psd'][t][p][b] # Select the color for the point (i.e., the brush and pen used # to render it) based on whether or not this datum's look # direction has been selected and whether or not the primary and # secondary selection states match. # if ( sel_bin == sel_alt ) : pen = self.pen_pnt_c brush = self.bsh_pnt_c # else : # pen = self.pen_pnt_y # brush = self.bsh_pnt_y # else : # pen = self.pen_pnt_r # brush = self.bsh_pnt_r # Select the symbol based on the values of the primary and # secondary selection states. # Note. At this point in the code, at least one of these two # states must be "True" since this -- when both states # are "False", this function returns before it reaches # this point. if ( sel_bin ) : symbol = 'o' else : symbol = 't' # Create, store, and add this selection point to the plot. if ( self.core.app.res_lo ) : size = 3 else : size = 6 self.pnt[t,p,b] = PlotDataItem( [ax], [ay], symbol=symbol, symbolSize=size, symbolPen=pen, symbolBrush=brush ) self.plt[t,p].addItem( self.pnt[t,p,b] ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR CREATING THE PLOTS' FIT CURVES. #----------------------------------------------------------------------- def make_crv( self ) : # If no "list" of "p" index-values has been provided by the # user, assume that the curves in all plots should be # (re-)rendered. if ( self.core.pl_spec_arr == [] ) : return # If the index of this P-L grid is outside the bounds of the P-L # spectrum currently loaded, abort. if ( self.n >= len( self.core.pl_spec_arr ) ) : return # Return the "nln_psd_gss_ion axes to their original order. if( self.core.nln_psd_gss_ion is not None ) : if( self.core.nln_psd_gss_ion != [ ] ) : nln_psd_gss_ion = [ [ [ [ [ self.core.nln_psd_gss_ion[n][t][f][b][p] for b in range( self.core.pl_spec_arr[n]['n_bin'] ) ] for f in range( self.core.pl_spec_arr[n]['n_phi'] ) ] for t in range( self.core.pl_spec_arr[n]['n_the'] ) ] for n in range( len( self.core.pl_spec_arr ) ) ] for p in range( self.core.nln_gss_n_pop ) ] # Return the "nln_res_psd_ion axes to their original order. if( self.core.nln_res_psd_ion is not None ) : if( self.core.nln_res_psd_ion != [ ] ) : nln_res_psd_ion = [ [ [ [ [ self.core.nln_res_psd_ion[n][t][f][b][p] for b in range( self.core.pl_spec_arr[n]['n_bin'] ) ] for f in range( self.core.pl_spec_arr[n]['n_phi'] ) ] for t in range( self.core.pl_spec_arr[n]['n_the'] ) ] for n in range( len( self.core.pl_spec_arr ) ) ] for p in range( self.core.nln_gss_n_pop ) ] # For each plot in the grid, generate and display a fit curve # based on the results of the analysis. vel_cen = self.core.pl_spec_arr[self.n]['vel_cen'] for t in range( self.core.pl_spec_arr[self.n]['n_the'] ) : for p in range( self.core.pl_spec_arr[self.n]['n_phi'] ) : # If this plot does not exist, move onto the next grid # element. if ( self.plt[t,p] is None ) : continue # If any curves already exist for this plot, remove and # delete them. if ( self.crv[t,p] is not None ) : self.plt[t,p].removeItem( self.crv[t,p] ) self.crv[t,p] = None for n in range( self.n_ion ) : if ( self.crv_ion[t,p,n] is not None ) : self.plt[t,p].removeItem( self.crv_ion[t,p,n] ) self.crv_ion[t,p,n] = None # Create and add the curve of the indiviadual # contributions to the modeled psd to the plot. for n in range( ( 1 if self.core.dsp == 'mom' else self.core.nln_gss_n_pop ) ) : # Extract the points for this fit curve. x = array( vel_cen ) if( self.core.dsp == 'mom' ) : y = array( self.core.pl_spec_arr[self.n]['psd_mom'][t][p] ) elif( self.core.dsp == 'gsl' ) : y = array( nln_psd_gss_ion[n][self.n][t][p] ) elif( self.core.dsp == 'nln' ) : y = array( nln_res_psd_ion[n][self.n][t][p] ) # If any points are 0 or None, set them # to an arbitrary minimum value for tk in range(len(y)): if ( ( y[tk] == 0 ) or ( y[tk] is None ) ) : y[tk] = 1e-20 if ( self.log_x ) : ax = log10( x ) else : ax = x if ( self.log_y ) : ay = array( [ log10( v ) for v in y ] ) else : ay = y # Create, store, and add to the plot # this fit curve. self.crv_ion[t,p,n] = PlotDataItem( ax, ay, pen=( self.pen_crv_b if self.core.dsp=='mom' else self.pen_crv_g ) ) self.plt[t,p].addItem( self.crv_ion[t,p,n] ) # If applicable, create and add the curve of the # total contributions to the modeled psd to the # plot if( self.core.dsp == 'gsl' ) : x = array( vel_cen ) y = array( self.core.nln_psd_gss_tot[self.n][t][p] ) # If any points are 0 or None, set them # to an arbitrary minimum value for tk in range(len(y)): if ( ( y[tk] == 0 ) or ( y[tk] is None ) ) : y[tk] = 1e-20 if ( self.log_x ) : ax = log10( x ) else : ax = x if ( self.log_y ) : ay = array( [ log10( v ) for v in y ] ) else : ay = y # Create, store, and add to the plot # this fit curve. self.crv[t,p] = PlotDataItem( ax, ay, pen=( self.pen_crv_b ) ) self.plt[t,p].addItem( self.crv[t,p] ) # If applicable, create and add the curve of the # total contributions to the non-linear psd to # the plot if( ( self.core.dsp == 'nln' ) and ( self.core.nln_res_psd_tot is not None ) ) : x = array( vel_cen ) y = array( self.core.nln_res_psd_tot[self.n][t][p] ) # If any points are 0 or None, set them # to an arbitrary minimum value for tk in range(len(y)): if ( ( y[tk] == 0 ) or ( y[tk] is None ) ) : y[tk] = 1e-20 if ( self.log_x ) : ax = log10( x ) else : ax = x if ( self.log_y ) : ay = array( [ log10( v ) for v in y ] ) else : ay = y # Create, store, and add to the plot # this fit curve. self.crv[t,p] = PlotDataItem( ax, ay, pen=( self.pen_crv_b ) ) self.plt[t,p].addItem( self.crv[t,p] ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESETTING THE PLOTS' HISTOGRAMS (AND LABELS). #----------------------------------------------------------------------- def rset_hst( self, rset_lbl=False ) : self.time_label.setText( '' ) self.t = [] self.delta_t = [] # For each plot that exists in the grid, remove and delete it's # histogram. Likewise, if requested, empty it's label (but # still leave the label itself intact). for t in range( self.n_plt_y ) : for p in range( self.n_plt_x ) : # If the plot does not exist, move onto the the # next one. if ( self.plt[t,p] is None ) : continue # If a histogram exists for this plot, remove # and delete it. if ( self.hst[t,p] is not None ) : self.plt[t,p].removeItem( self.hst[t,p] ) self.hst[t,p] = None # If requested, reset this plot's label text to # the empty string. if ( rset_lbl ) : self.lbl[t,p].setText( '', color=(0,0,0) ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESETTING THE PLOTS' SELECTION POINTS. #----------------------------------------------------------------------- def rset_pnt( self ) : # For each plot that exists in the grid, hide and remove its # selection points. for t in range( self.n_plt_y ) : for p in range( self.n_plt_x ) : # If the plot does not exist, move onto the the # next grid element. if ( self.plt[t,p] is None ) : continue # Remove and then delete each of this plot's # selection points. for b in range( self.n_k ) : if ( self.pnt[t,p,b] is not None ) : self.plt[t,p].removeItem( self.pnt[t,p,b] ) self.pnt[t,p,b] = None #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESETTING THE PLOTS' FIT CURVES. #----------------------------------------------------------------------- def rset_crv( self ) : # For each plot that exists in the grid, remove and delete its # fit curves. for t in range( self.n_plt_y ) : for p in range( self.n_plt_x ) : # If the plot does not exist, move onto the the # next one. if ( self.plt[t,p] is None ) : continue # Remove and delete this plot's fit curve. if ( self.crv[t,p] is not None ) : self.plt[t,p].removeItem( self.crv[t,p] ) self.crv[t,p] = None for n in range( self.n_ion ) : if ( self.crv_ion[t,p,n] is not None ) : self.plt[t,p].removeItem( self.crv_ion[t,p,n] ) self.crv_ion[t,p,n] = None #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "rset" SIGNAL. #----------------------------------------------------------------------- def resp_rset( self ) : # Clear the plots of all their elements. self.rset_hst( ) self.rset_pnt( ) self.rset_crv( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_spc" SIGNAL. #----------------------------------------------------------------------- def resp_chng_pl_spc( self ) : # Clear the plots of all their elements and regenerate them. self.rset_crv( ) self.rset_pnt( ) self.rset_hst( ) self.make_hst( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_mom_pl_res" SIGNAL. #----------------------------------------------------------------------- def resp_chng_mom_pl_sel( self ) : # If the results of the moments analysis are being displayed, # reset any existing fit curves and make new ones. self.make_pnt( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_mom_pl_res" SIGNAL. #----------------------------------------------------------------------- def resp_chng_mom_pl_res( self ) : # If the results of the moments analysis are being displayed, # reset any existing fit curves and make new ones. self.make_crv( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_nln_gss" SIGNAL. #----------------------------------------------------------------------- def resp_chng_nln_gss( self ) : # If the initial guess for the non-linear analysis is being # displayed, reset any existing fit curves and make new ones. if ( self.core.dsp == 'gsl' ) : self.make_crv( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_nln_sel_all" SIGNAL. #----------------------------------------------------------------------- def resp_chng_nln_sel_all( self ) : # If the point selection for the non-linear analysis is being # displayed, reset any existing selection points and create new # ones. if ( ( self.core.dsp == 'gsl' ) or ( self.core.dsp == 'nln' ) ) : self.make_pnt( ) # self.make_crv( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_dsp" SIGNAL. #----------------------------------------------------------------------- def resp_chng_dsp( self ) : # Reset the selection points and fit curves. self.make_pnt( ) self.make_crv( ) #----------------------------------------------------------------------- # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_dsp" SIGNAL. #----------------------------------------------------------------------- def resp_chng_nln_res( self ) : # Reset the fit curves. self.make_crv( ) '''
class MainWindow(QWidget): stravaCredentials = pyqtSignal(str, str) clearedStravaCredentials = pyqtSignal() abortUpload = pyqtSignal() def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self._createWidgets() self._createLayout() self._showLoading('Searching for device') self._createWorkerThread() QTimer.singleShot(1000, self._bb_client.onStart) def _onUnsupportedVersion(self, ver): self.warning_label.setText( 'You are using an unsupported version of BrytonBridge. ' 'It may or may not work as expected. ' 'Supported versions are (%s)' % (', '.join(SUPPORTED_VERSIONS),) ) self.warning_label.show() def _onUploadStarted(self, tracks): self.upload_progress.setTracks(tracks) self._showWidget(self.upload_progress) def _onUploadStatus(self, msg): self._showLoading(msg) def _abortUpload(self): self.abortUpload.emit() self._showWidget(self.tracklist) def _onNeedLogin(self): login = LoginDialog(self) if login.exec_() == QDialog.Accepted: u = login.username.text() p = login.password.text() if login.remember.checkState() == Qt.Checked: self._saveStravaCredentials(u, p) self.stravaCredentials.emit(u, p) else: self._abortUpload() def _onTracksReady(self, tracks): self.tracklist.setTracks(tracks) self._showWidget(self.tracklist) def _onError(self, msg): self._showMessage('Error: %s' % msg, resource_path('images/cry.png')) def _onDeviceOffline(self): self._showMessage('Please connect your device', resource_path('images/connect.png')) def _showMessage(self, msg, icon): self.messages.setMessage(msg) self.messages.setIcon(icon) self._showWidget(self.messages) def _showLoading(self, msg): self.loading.setMessage(msg) self._showWidget(self.loading) def _showWidget(self, widget): self.widgets.setCurrentWidget(widget) def _onClearPassword(self): settings = self._getSettings() settings.remove('strava/username') settings.remove('strava/password') self.clearedStravaCredentials.emit() self.tracklist.clear_password.hide() def _getStravaCredentials(self): settings = self._getSettings() u = settings.value('strava/username').toString() p = settings.value('strava/password').toString() if not u or not p: return None, None return u, p def _saveStravaCredentials(self, username, password): settings = self._getSettings() settings.setValue('strava/username', username) settings.setValue('strava/password', password) self.tracklist.clear_password.show() def _getSettings(self): return QSettings('BrytonGPS', 'BrytonStravaUploader') def _createWorkerThread(self): self._worker_thread = QThread(self) u, p = self._getStravaCredentials() self._bb_client = BBClient(strava_username=u, strava_password=p) self._bb_client.moveToThread(self._worker_thread) self._worker_thread.started.connect(self._bb_client._onThreadStart) self._worker_thread.finished.connect(self._bb_client.deleteLater) self._bb_client.tracksReady.connect(self._onTracksReady) self._bb_client.error.connect(self._onError) self._bb_client.deviceOffline.connect(self._onDeviceOffline) self._bb_client.stravaCredentialsNeeded.connect(self._onNeedLogin) self._bb_client.unsupportedBBVersion.connect(self._onUnsupportedVersion) self._bb_client.uploadStatus.connect(self._onUploadStatus) self._bb_client.stravaUploadStarted.connect(self._onUploadStarted) self._bb_client.stravaUploadProgress.connect( self.upload_progress.updateProgress) self._bb_client.stravaUploadFinished.connect( self.upload_progress.onFinished) self.abortUpload.connect(self._bb_client.onAbortUpload) self.stravaCredentials.connect(self._bb_client.onStravaCredentials) self.clearedStravaCredentials.connect( self._bb_client.onClearStravaCredentials) self.tracklist.requestUpload.connect(self._bb_client.onUploadTracks) self._worker_thread.start() def _createWidgets(self): self.widgets = QStackedWidget(self) self.warning_label = QLabel(self) self.warning_label.setStyleSheet( "QLabel { background-color : #FF8383;}") self.warning_label.setWordWrap(True) self.warning_label.setContentsMargins(5, 5, 5, 5) self.warning_label.hide() self.loading = LoadingWidget(self) self.messages = IconWidget(self) self.tracklist = TracklistWidget(self) self.upload_progress = UploadProgressWidget(self) self.widgets.addWidget(self.loading) self.widgets.addWidget(self.messages) self.widgets.addWidget(self.tracklist) self.widgets.addWidget(self.upload_progress) settings = self._getSettings() if settings.contains('strava/username') or \ settings.contains('strava/password'): self.tracklist.clear_password.show() self.tracklist.clear_password.clicked.connect(self._onClearPassword) self.upload_progress.close_button.clicked.connect(self._showTracklist) def _showTracklist(self): self._showWidget(self.tracklist) def _createLayout(self): l = QVBoxLayout() l.setContentsMargins(0, 0, 0, 0) l.addWidget(self.warning_label) logo = QLabel(self) pix = QPixmap(resource_path('images/logo.png')) pix = pix.scaledToWidth(400, Qt.SmoothTransformation) logo.setPixmap(pix) l.addWidget(logo) l.addWidget(self.widgets, 1) self.setLayout(l)
class PreviewDialog(QDialog): """A Dialog for selecting an item from a PreviewItem. """ currentIndexChanged = Signal(int) def __init__(self, parent=None, flags=Qt.WindowFlags(0), model=None, **kwargs): QDialog.__init__(self, parent, flags, **kwargs) self.__setupUi() if model is not None: self.setModel(model) def __setupUi(self): layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setContentsMargins(0, 0, 0, 0) heading = self.tr("Preview") heading = "<h3>{0}</h3>".format(heading) self.__heading = QLabel(heading, self, objectName="heading") self.__heading.setContentsMargins(12, 12, 12, 0) self.__browser = previewbrowser.PreviewBrowser(self) self.__buttons = QDialogButtonBox(QDialogButtonBox.Open | \ QDialogButtonBox.Cancel, Qt.Horizontal,) self.__buttons.button(QDialogButtonBox.Open).setAutoDefault(True) # Set the Open dialog as disabled until the current index changes self.__buttons.button(QDialogButtonBox.Open).setEnabled(False) # The QDialogButtonsWidget messes with the layout if it is # contained directly in the QDialog. So we create an extra # layer of indirection. buttons = QWidget(objectName="button-container") buttons_l = QVBoxLayout() buttons_l.setContentsMargins(12, 0, 12, 12) buttons.setLayout(buttons_l) buttons_l.addWidget(self.__buttons) layout.addWidget(self.__heading) layout.addWidget(self.__browser) layout.addWidget(buttons) self.__buttons.accepted.connect(self.accept) self.__buttons.rejected.connect(self.reject) self.__browser.currentIndexChanged.connect( self.__on_currentIndexChanged ) self.__browser.activated.connect(self.__on_activated) layout.setSizeConstraint(QVBoxLayout.SetFixedSize) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) def setItems(self, items): """Set the items (a list of strings) for preview/selection. """ model = QStringListModel(items) self.setModel(model) def setModel(self, model): """Set the model for preview/selection. """ self.__browser.setModel(model) def model(self): """Return the model. """ return self.__browser.model() def currentIndex(self): return self.__browser.currentIndex() def setCurrentIndex(self, index): """Set the current selected (shown) index. """ self.__browser.setCurrentIndex(index) def setHeading(self, heading): """Set `heading` as the heading string ('<h3>Preview</h3>' by default). """ self.__heading.setText(heading) def heading(self): """Return the heading string. """ def __on_currentIndexChanged(self, index): button = self.__buttons.button(QDialogButtonBox.Open) button.setEnabled(index >= 0) self.currentIndexChanged.emit(index) def __on_activated(self, index): if self.currentIndex() != index: self.setCurrentIndex(index) self.accept()
class DeviceInfoWidget(QWidget): DEVICE_IMAGES = { 'rider20' : resource_path('img/rider20_icon.jpg'), 'rider30' : resource_path('img/rider30_icon.jpg'), 'rider35' : resource_path('img/rider35_icon.jpg'), 'rider40' : resource_path('img/rider40_icon.jpg'), 'rider50' : resource_path('img/rider50_icon.jpg'), 'rider' : resource_path('img/rider_icon.jpg'), 'cardio30' : resource_path('img/cardio30_icon.jpg'), 'cardio35' : resource_path('img/cardio35_icon.jpg'), 'cardio' : resource_path('img/cardio_icon.jpg'), } def __init__(self, parent=None): super(DeviceInfoWidget, self).__init__(parent) self.image = QLabel(self) self.image.setPixmap(QPixmap(self.DEVICE_IMAGES['rider'])) self.image_frame = QFrame(self) self.image_frame.setMaximumHeight(55) self.image_frame.setMinimumHeight(55) self.image_frame.setMaximumWidth(55) self.image_frame.setMinimumWidth(55) self.image_frame.setFrameShape(QFrame.StyledPanel) self.image_frame.setFrameShadow(QFrame.Raised) self.storage_usage = QProgressBar(self) self.storage_usage.setFormat('Disk usage %p%') self.storage_usage.setRange(0, 100) self.storage_usage.setValue(0) self.device_name = QLabel(self) self.device_name.setText('<b>Unknown</b>') self.device_name.setContentsMargins(3, 0, 0, 0) self._createLayout() def setDeviceInfo(self, dev_info): name = dev_info['name'].lower() if name in self.DEVICE_IMAGES: img = self.DEVICE_IMAGES[name] elif 'rider' in name: img = self.DEVICE_IMAGES['rider'] elif 'cardio' in name: img = self.DEVICE_IMAGES['cardio'] else: img = self.DEVICE_IMAGES['rider'] self.device_name.setText('<b>%s</b>' % dev_info['name']) self.image.setPixmap(QPixmap(img)) self.storage_usage.setValue( float(dev_info['storage_used']) / dev_info['total_storage'] * 100 ) def _createLayout(self): l = QHBoxLayout() l.addWidget(self.image) l.setContentsMargins(1, 1, 1, 1) self.image_frame.setLayout(l) l = QHBoxLayout() l.addWidget(self.image_frame) v = QVBoxLayout() v.addWidget(self.device_name) v.addWidget(self.storage_usage, 1) l.addLayout(v) self.setLayout(l)
def __init__(self, data): data = data or self.DEFAULT_SETTINGS PreprocessorModule.__init__( self, 'Token filtering', True, data.get('is_enabled') ) self.group = QButtonGroup(self, exclusive=False) # --- English --- cb = QCheckBox(self, text=self.filter_names[self.English]) self.add_to_content_area(cb) self.group.addButton(cb, self.English) # --- Custom --- cb = QCheckBox(self, text=self.filter_names[self.Custom]) self.add_to_content_area(cb) self.group.addButton(cb, self.Custom) # File browser. file_browser_layout = QHBoxLayout() file_browser_layout.setContentsMargins(20, 0, 0, 0) self.sw_file_combo = QComboBox() self.sw_file_combo.setMinimumWidth(200) file_browser_layout.addWidget(self.sw_file_combo) self.sw_file_combo.activated[int].connect(self.select_file) self.browse_button = QPushButton(self) self.browse_button.clicked.connect(self.browse_file) self.browse_button.setIcon(self.style() .standardIcon(QStyle.SP_DirOpenIcon)) self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) file_browser_layout.addWidget(self.browse_button) # Reload button self.reload_button = QPushButton(self) self.reload_button.clicked.connect(self.on_reload_button_clicked) self.reload_button.setIcon(self.style() .standardIcon(QStyle.SP_BrowserReload)) self.reload_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) file_browser_layout.addWidget(self.reload_button) self.add_layout_to_content_area(file_browser_layout) # --- DF --- df_info_text = """ Remove all tokens that appear in less than 'min-df' documents. Remove all tokens that appear in more than 'max-df' documents. Values can be either integers or floats (ratio of documents). """ cb = QCheckBox(self, text=self.filter_names[self.DocumentFrequency]) self.add_to_content_area(cb) self.group.addButton(cb, self.DocumentFrequency) df_info_text = QLabel(df_info_text) df_info_text.setContentsMargins(0,0,0,0) df_info_text.setStyleSheet(""" font-size: 11px; font-style: italic; """) self.add_to_content_area(df_info_text) # Min/Max-Df setter. df_setter_layout = QHBoxLayout() df_setter_layout.setContentsMargins(20, 0, 0, 0) self.min_df_input = QLineEdit() self.min_df_input.textChanged.connect(self.update_df_parameters) self.max_df_input = QLineEdit() self.max_df_input.textChanged.connect(self.update_df_parameters) df_setter_layout.addWidget(QLabel('Min-df:')) df_setter_layout.addWidget(self.min_df_input) df_setter_layout.addWidget(QLabel('Max-df:')) df_setter_layout.addWidget(self.max_df_input) self.add_layout_to_content_area(df_setter_layout) self.group.buttonClicked.connect(self.group_button_clicked) # Restore the widget to its previous state. self.restore_data(data)
def __init__(self, data): data = data or self.DEFAULT_SETTINGS PreprocessorModule.__init__(self, 'Token filtering', True, data.get('is_enabled')) self.group = QButtonGroup(self, exclusive=False) # --- English --- cb = QCheckBox(self, text=self.filter_names[self.English]) self.add_to_content_area(cb) self.group.addButton(cb, self.English) # --- Custom --- cb = QCheckBox(self, text=self.filter_names[self.Custom]) self.add_to_content_area(cb) self.group.addButton(cb, self.Custom) # File browser. file_browser_layout = QHBoxLayout() file_browser_layout.setContentsMargins(20, 0, 0, 0) self.sw_file_combo = QComboBox() self.sw_file_combo.setMinimumWidth(200) file_browser_layout.addWidget(self.sw_file_combo) self.sw_file_combo.activated[int].connect(self.select_file) self.browse_button = QPushButton(self) self.browse_button.clicked.connect(self.browse_file) self.browse_button.setIcon(self.style().standardIcon( QStyle.SP_DirOpenIcon)) self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) file_browser_layout.addWidget(self.browse_button) # Reload button self.reload_button = QPushButton(self) self.reload_button.clicked.connect(self.on_reload_button_clicked) self.reload_button.setIcon(self.style().standardIcon( QStyle.SP_BrowserReload)) self.reload_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) file_browser_layout.addWidget(self.reload_button) self.add_layout_to_content_area(file_browser_layout) # --- DF --- df_info_text = """ Remove all tokens that appear in less than 'min-df' documents. Remove all tokens that appear in more than 'max-df' documents. Values can be either integers or floats (ratio of documents). """ cb = QCheckBox(self, text=self.filter_names[self.DocumentFrequency]) self.add_to_content_area(cb) self.group.addButton(cb, self.DocumentFrequency) df_info_text = QLabel(df_info_text) df_info_text.setContentsMargins(0, 0, 0, 0) df_info_text.setStyleSheet(""" font-size: 11px; font-style: italic; """) self.add_to_content_area(df_info_text) # Min/Max-Df setter. df_setter_layout = QHBoxLayout() df_setter_layout.setContentsMargins(20, 0, 0, 0) self.min_df_input = QLineEdit() self.min_df_input.textChanged.connect(self.update_df_parameters) self.max_df_input = QLineEdit() self.max_df_input.textChanged.connect(self.update_df_parameters) df_setter_layout.addWidget(QLabel('Min-df:')) df_setter_layout.addWidget(self.min_df_input) df_setter_layout.addWidget(QLabel('Max-df:')) df_setter_layout.addWidget(self.max_df_input) self.add_layout_to_content_area(df_setter_layout) self.group.buttonClicked.connect(self.group_button_clicked) # Restore the widget to its previous state. self.restore_data(data)
class MainWindow(QWidget): def __init__(self, config, parent=None): super(MainWindow, self).__init__(parent) self.bbclient = BrytonClient(parent=self, server_host=config.get('server_host')) self.history_list_widget = HistoryWidget(self.bbclient, config, self) self.device_info_widget = DeviceInfoWidget(self) self.track_summary_widget = TrackSummaryWidget(self) self.track_tabs = QTabWidget(self) self.track_tabs.setMaximumWidth(200) self.track_tabs.addTab(self.history_list_widget, 'History') self.history_list_widget.currentTrackChanged.connect(self._onHistoryTrackChanged) self.bb_version = QLabel('', self) self.bb_version.setAlignment(Qt.AlignRight) self.bb_version.setContentsMargins(0, 0, 3, 0) self._createLayout() self.message_overlay = MessageWidget(self) self.message_overlay.setLoading('Connecting to BrytonBridge') self.message_overlay.retryClicked.connect(self._onRetry) self.bbclient.statusMessage.connect(self.message_overlay.setLoading) self.bbclient.connected.connect(self._onConnected) self.bbclient.deviceOffline.connect(self._onDeviceOffline) self.bbclient.deviceReady.connect(self._onDeviceReady) self.bbclient.trackListReady.connect(self._onTrackListReady) self.bbclient.error.connect(self._onError) self.bbclient.BBVersion.connect(self._onBBVersion) self.bbclient.start() # self.message_overlay.hide() def _onConnected(self): self.message_overlay.setMessage('Searching for device') def _onDeviceReady(self): self.device_info_widget.setDeviceInfo(self.bbclient.dev_state) self.message_overlay.hide() def _onDeviceOffline(self): self.message_overlay.setDisconnected('Please connect your device') self.message_overlay.show() def _onError(self, msg): self.message_overlay.setError(msg) self.message_overlay.retry.show() self.message_overlay.show() def _onRetry(self): self.message_overlay.retry.hide() self.bbclient.reset() self.bbclient.start() def _onBBVersion(self, version): if version in TESTED_VERSIONS: self.bb_version.hide() self.bb_version.setText('BrytonBridge version <font color="green">{}</font>'.format(version)) else: self.bb_version.show() self.bb_version.setText('BrytonBridge version <font color="red"><b>{}</b></font>'.format(version)) self.bb_version.setToolTip('You are using an untested version of BrytonBridge') def _onTrackListReady(self): self.tracks = tracks = self.bbclient.track_list self.history_list_widget.setTrackList(tracks, self.bbclient.dev_state) def _onHistoryTrackChanged(self, track): self.track_summary_widget.setTrack(track) def resizeEvent(self, event): self.message_overlay.resize(event.size()) super(MainWindow, self).resizeEvent(event) def _createLayout(self): la = QVBoxLayout() la.addWidget(self.bb_version) l = QHBoxLayout() l.addWidget(self.track_tabs, 0) v = QVBoxLayout() group = QGroupBox('Device', self) l2 = QHBoxLayout() l2.addWidget(self.device_info_widget) group.setLayout(l2) v.addWidget(group) group = QGroupBox('Track Summary', self) l2 = QHBoxLayout() l2.addWidget(self.track_summary_widget) group.setLayout(l2) v.addWidget(group, 1) l.addLayout(v, 1) la.addLayout(l) self.setLayout(la)