class TableView(Frame):
    OPTIONS = {'font': ('bold', 11)}

    def __init__(self, window, **kwargs):
        super().__init__(window, **kwargs)
        self.tree = Treeview(self, selectmode='browse')
        self.tree.column("#0", width=100, minwidth=75, stretch=NO)
        self.tree.heading("#0", text='row', anchor='center')
        self.scroll = Scrollbar(self, command=self.tree.yview)
        self.tree.config(yscrollcommand=self.scroll.set)
        self.scroll.pack(side=RIGHT, fill=Y)
        self.tree.pack(expand=True, side=LEFT, fill=BOTH)

    def create_columns(self, *columns):
        for column in columns:
            self.tree.column(f"{column}", width=150, minwidth=150, stretch=YES)

    def create_heading(self, *columns):
        for index, column in enumerate(columns):
            self.tree.heading(f"#{index+1}", text=f"{column}", anchor='center')

    def fill_row(self, *args):
        if args:
            self.tree.delete(*self.tree.get_children())
            for index, contact in enumerate(args):
                self.tree.insert("",
                                 'end',
                                 contact.id,
                                 text=f"{index+1}",
                                 values=list(contact.informations.values()))
        else:
            return
Exemple #2
0
    def listVideos(self, chan, target):
        self.center = target
        #get chan id
        chanid = database.get_channel_id(chan)
        vids = database.get_channel_videos(chanid)

        tree = Treeview(self.center)
        tree["columns"] = ("one", "two")

        tree.column("#0", width=20, minwidth=10, stretch=YES)
        tree.column("one", width=390, minwidth=250, stretch=YES)
        tree.column("two", width=200, minwidth=40)

        tree.heading("#0", text="ID", anchor=W)
        tree.heading("one", text="Title", anchor=W)
        tree.heading("two", text="Date", anchor=W)
        i = 0
        tree.tag_configure('oddrow', background='#88DD88')
        tree.tag_configure('evenrow', background='#FFFFFF')

        for videodata in vids:
            foldername = "folder" + str(i)
            if i % 2 == 0:
                color = "evenrow"
            else:
                color = "oddrow"
            # tree.insert("", 1, "", text="Folder 1", values=("23-Jun-17 11:05","File folder",""))
            ts = int(videodata.publish_date)
            foldername = tree.insert("",
                                     "end",
                                     text=videodata.yt_videoid,
                                     values=(videodata.title, time.ctime(ts)),
                                     tags=(color))
            #tree.insert(folder1, "end", "", text="photo1.png", values=("23-Jun-17 11:28","PNG file","2.6 KB"))
            tree.insert(foldername,
                        "end",
                        text="desc",
                        values=(videodata.description, videodata.watched),
                        tags=(color))
            i = i + 1

        vertscroll = Scrollbar(self.center)
        vertscroll.config(command=tree.yview)
        tree.config(yscrollcommand=vertscroll.set)
        tree.bind("<Button-" + config.mousebuttons + ">",
                  self.video_action_window)
        tree.grid(row=5, columnspan=3, sticky="NSEW")
Exemple #3
0
 def config_table(self, table: ttk.Treeview, **kwds) -> None:
     """Method for a table configuration."""
     height = kwds.get('height', 24)
     columns = kwds.get('columns', [''])
     show = kwds.get('show', 'headings')
     headwidths = kwds.get('headwidths', [490])
     selectmode = kwds.get('selectmode', 'extended')
     table.config(selectmode=selectmode,
                  columns=columns,
                  height=height,
                  show=show)
     for heading, headwidth in zip(columns, headwidths):
         table.heading(heading, text=heading, anchor=CENTER)
         table.column(heading,
                      width=headwidth,
                      minwidth=headwidth - 8,
                      anchor=W)
Exemple #4
0
    def setupTreeView(self):
        #probably want treeview, not listbox
        scr_w = 180
        scr_h = 10

        tabConfig = configRoot.findall('treeview/tab')
        self.tabLabelList = []
        self.headingDict = {}

        for t in tabConfig:
            tabName = t.attrib['label']
            self.tabLabelList.append(tabName)
            headingConfig = t.findall('heading')
            temp = []
            for h in headingConfig:
                temp.append(h.attrib['label'])
                self.headingDict[tabName] = temp.copy()
            temp.clear()

        print(self.headingDict)
        for tab in self.tabControl.winfo_children():
            # listbox = Listbox(tab, width = 120)
            # listbox.grid(column = 0, row = 0, padx = 20, pady = 10)
            tabText = self.tabControl.tab(tab)['text']

            treeview = Treeview(tab)
            #treeview['columns'] = ('Title', 'Author', 'Platform')
            treeview['columns'] = self.headingDict[tabText]
            treeview.heading("#0", text="ID")
            treeview.column('#0', minwidth=50, width=50, stretch=False)
            for h in treeview['columns']:
                print(h)
                treeview.heading(h, text=h)
            treeview.grid(
                column=0,
                row=0,
                sticky="NSEW",
            )
            treeview.bind("<Double-1>", self.itemSelected)
            treeview.config(height=25)

            scrollbar = Scrollbar(tab)
            scrollbar.grid(column=1, row=0, sticky="NS")
            treeview.config(yscrollcommand=scrollbar.set)
            scrollbar.config(command=treeview.yview)
Exemple #5
0
    def show_feed(self, body, value):
        center = body
        tree = Treeview(center)
        tree["columns"] = ("one", "two")

        tree.column("#0", width=20, minwidth=10, stretch=YES)
        tree.column("one", width=390, minwidth=250, stretch=YES)
        tree.column("two", width=200, minwidth=40)

        tree.heading("#0", text="ID", anchor=W)
        tree.heading("one", text="Title", anchor=W)
        tree.heading("two", text="Date", anchor=W)
        i = 0
        tree.tag_configure('oddrow', background='#88DD88')
        tree.tag_configure('evenrow', background='#FFFFFF')
        vids = self.get_feed(value)
        for videodata in vids:
            foldername = "folder" + str(i)
            if i % 2 == 0:
                color = "evenrow"
            else:
                color = "oddrow"
            ts = int(videodata.publish_date)

            foldername = tree.insert("",
                                     "end",
                                     text=i,
                                     values=(videodata.title, time.ctime(ts)),
                                     tags=(color))

            tree.insert(foldername,
                        "end",
                        text="desc",
                        values=(videodata.description, ""),
                        tags=(color))
            i = i + 1

        vertscroll = Scrollbar(center)
        vertscroll.config(command=tree.yview)
        tree.config(yscrollcommand=vertscroll.set)
        tree.grid(row=5, columnspan=3, sticky="NSEW")

        vertscroll.grid(column=3, row=5, sticky='NSE')
def consultar(buscartabla):
    name = buscartabla
    # fetch(buscartabla)
    filewin = Toplevel(root)
    frame_router = Frame(filewin)
    frame_router.grid(row=4,
                      column=0,
                      columnspan=4,
                      rowspan=6,
                      pady=20,
                      padx=20)
    buscarColumnas = """PRAGMA table_info({});""".format(buscartabla)
    infoTabla = CursorSql.execute(buscarColumnas)

    buscartabla = []
    for campo in infoTabla:
        buscartabla.append(campo[1])
    #end for
    query = f"select * from '{name}'"
    dataTable = CursorSql.execute(query).fetchall()
    # print(dataTable[0][0])
    columns = buscartabla
    router_tree_view = Treeview(frame_router, columns=columns, show="headings")
    router_tree_view.column(buscartabla[0], width=100)
    for col in columns[0:]:
        router_tree_view.column(col, width=120)
        router_tree_view.heading(col, text=col)
    #end for
    if type(dataTable) is list:
        for data in dataTable:
            i = 0
            router_tree_view.insert('', i, values=dinamyFill(name, data))
            i = i + 1
    #end for
    router_tree_view.pack(side="left", fill="y")
    scrollbar = Scrollbar(frame_router, orient='vertical')
    scrollbar.configure(command=router_tree_view.yview)
    scrollbar.pack(side="right", fill="y")
    router_tree_view.config(yscrollcommand=scrollbar.set)
    filewin.geometry("400x300")
    filewin.mainloop()
class DialogOpenArchive(Toplevel):
    def __init__(self,
                 parent,
                 openType,
                 filesource,
                 filenames,
                 title,
                 colHeader,
                 showAltViewButton=False,
                 multiselect=False):
        if isinstance(parent, Cntlr):
            cntlr = parent
            parent = parent.parent  # parent is cntlrWinMain
        else:  # parent is a Toplevel dialog
            cntlr = parent.cntlr
        super(DialogOpenArchive, self).__init__(parent)
        self.parent = parent
        self.showAltViewButton = showAltViewButton
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)",
                                  parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))
        self.accepted = False

        self.transient(self.parent)

        frame = Frame(self)

        treeFrame = Frame(frame, width=500)
        vScrollbar = Scrollbar(treeFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(treeFrame, orient=HORIZONTAL)
        self.treeView = Treeview(treeFrame,
                                 xscrollcommand=hScrollbar.set,
                                 yscrollcommand=vScrollbar.set)
        self.treeView.grid(row=0, column=0, sticky=(N, S, E, W))
        self.treeView.config(
            selectmode="extended" if multiselect else "browse")
        hScrollbar["command"] = self.treeView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E, W))
        vScrollbar["command"] = self.treeView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N, S))
        treeFrame.columnconfigure(0, weight=1)
        treeFrame.rowconfigure(0, weight=1)
        treeFrame.grid(row=0,
                       column=0,
                       columnspan=4,
                       sticky=(N, S, E, W),
                       padx=3,
                       pady=3)
        self.treeView.focus_set()

        if openType not in (PLUGIN, PACKAGE):
            cntlr.showStatus(_("loading archive {0}").format(filesource.url))
        self.filesource = filesource
        self.filenames = filenames
        self.selection = filesource.selection
        self.hasToolTip = False
        self.multiselect = multiselect
        selectedNode = None

        if openType == ENTRY_POINTS:
            try:
                metadataFiles = filesource.taxonomyPackageMetadataFiles
                ''' take first for now
                if len(metadataFiles) != 1:
                    raise IOError(_("Taxonomy package contained more than one metadata file: {0}.")
                                  .format(', '.join(metadataFiles)))
                '''
                metadataFile = metadataFiles[0]
                metadata = filesource.url + os.sep + metadataFile
                self.metadataFilePrefix = os.sep.join(
                    os.path.split(metadataFile)[:-1])
                if self.metadataFilePrefix:
                    self.metadataFilePrefix += "/"  # zip contents have /, never \ file seps
                self.taxonomyPkgMetaInf = '{}/META-INF/'.format(
                    os.path.splitext(os.path.basename(filesource.url))[0])

                self.taxonomyPackage = parsePackage(
                    cntlr, filesource, metadata,
                    os.sep.join(os.path.split(metadata)[:-1]) + os.sep)

                if self.taxonomyPackage["entryPoints"]:
                    # may have instance documents too
                    self.packageContainedInstances = []
                    self.packageContainedIXDSes = defaultdict(list)
                    packageContentInstanceCounts = {}
                    packageContentTypeCounts = {}
                    for suffix in (
                            ".xhtml", ".htm", ".html"
                    ):  # try for suffixes in order of likelihood to have instance
                        for potentialInstance in filesource.dir:
                            if potentialInstance.endswith(suffix):
                                m = reportIxdsPattern.match(
                                    potentialInstance)  # IXDS
                                if multiselect and m:  # only in ixds multiselect mode
                                    _type = "Inline Doc Set"
                                    self.packageContainedIXDSes[m.group(
                                        1)].append(potentialInstance)
                                    potentialInstance = m.group(
                                        1)  # use package name only
                                else:
                                    _type = "Inline Instance"
                                if not self.packageContainedInstances or self.packageContainedInstances[
                                        -1][0] != potentialInstance:
                                    self.packageContainedInstances.append(
                                        [potentialInstance, _type])
                                    packageContentInstanceCounts[
                                        potentialInstance] = packageContentInstanceCounts.get(
                                            potentialInstance, 0) + 1
                                    packageContentTypeCounts[
                                        _type] = packageContentTypeCounts.get(
                                            _type, 0) + 1
                        if self.packageContainedInstances:
                            break
                    if self.packageContainedInstances:  # add sequences to any duplicated entry types
                        for _type, count in packageContentTypeCounts.items():
                            if count > 1:
                                _dupNo = 0
                                for i in range(
                                        len(self.packageContainedInstances)):
                                    if self.packageContainedInstances[i][
                                            1] == _type:
                                        _dupNo += 1
                                        self.packageContainedInstances[i][
                                            1] = "{} {}".format(_type, _dupNo)
                        for _instance, count in packageContentInstanceCounts.items(
                        ):
                            if count > 1:
                                _dupNo = 0
                                for i in range(
                                        len(self.packageContainedInstances)):
                                    if self.packageContainedInstances[i][
                                            0] == _instance:
                                        _dupNo += 1
                                        self.packageContainedInstances[i][
                                            0] = "{} {}".format(
                                                _instance, _dupNo)

                else:
                    # may be a catalog file with no entry oint names
                    openType = ARCHIVE  # no entry points to show, just archive
                    self.showAltViewButton = False
            except Exception as e:
                self.close()
                err = _(
                    "Failed to parse metadata; the underlying error was: {0}"
                ).format(e)
                messagebox.showerror(_("Malformed taxonomy package"), err)
                cntlr.addToLog(err)
                return

        if openType not in (PLUGIN, PACKAGE):
            cntlr.showStatus(None)

        if openType in (DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
            y = 3
        else:
            y = 1

        okButton = Button(frame, text=_("OK"), command=self.ok)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        okButton.grid(row=y, column=2, sticky=(S, E, W), pady=3)
        cancelButton.grid(row=y, column=3, sticky=(S, E, W), pady=3, padx=3)

        if self.showAltViewButton:
            self.altViewButton = Button(frame, command=self.showAltView)
            self.altViewButton.grid(row=y,
                                    column=0,
                                    sticky=(S, W),
                                    pady=3,
                                    padx=3)

        self.loadTreeView(openType, colHeader, title)

        self.geometry("+{0}+{1}".format(dialogX + 50, dialogY + 100))
        frame.grid(row=0, column=0, sticky=(N, S, E, W))
        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        window.rowconfigure(0, weight=1)

        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)

        self.toolTipText = StringVar()
        if self.hasToolTip:
            self.treeView.bind("<Motion>", self.motion, '+')
            self.treeView.bind("<Leave>", self.leave, '+')
            self.toolTipText = StringVar()
            self.toolTip = ToolTip(self.treeView,
                                   textvariable=self.toolTipText,
                                   wraplength=640,
                                   follow_mouse=True,
                                   state="disabled")
            self.toolTipRowId = None

        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()

        self.wait_window(self)

    def loadTreeView(self, openType, title, colHeader):
        self.title(title)
        self.openType = openType
        selectedNode = None

        # clear previous treeview entries
        for previousNode in self.treeView.get_children(""):
            self.treeView.delete(previousNode)

        # set up treeView widget and tabbed pane
        if openType in (ARCHIVE, DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
            if openType in (PLUGIN, PACKAGE): width = 770
            else: width = 500
            self.treeView.column("#0", width=width, anchor="w")
            self.treeView.heading("#0", text=colHeader)
            self.isRss = getattr(self.filesource, "isRss", False)
            if self.isRss:
                self.treeView.column("#0", width=350, anchor="w")
                self.treeView["columns"] = ("descr", "date", "instDoc")
                self.treeView.column("descr",
                                     width=50,
                                     anchor="center",
                                     stretch=False)
                self.treeView.heading("descr", text="Form")
                self.treeView.column("date",
                                     width=170,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("date", text="Pub Date")
                self.treeView.column("instDoc",
                                     width=200,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("instDoc", text="Instance Document")
            elif openType == PLUGIN:
                self.treeView.column("#0", width=150, anchor="w")
                self.treeView["columns"] = ("name", "vers", "descr", "license")
                self.treeView.column("name",
                                     width=150,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("name", text="Name")
                self.treeView.column("vers",
                                     width=60,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("vers", text="Version")
                self.treeView.column("descr",
                                     width=300,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("descr", text="Description")
                self.treeView.column("license",
                                     width=60,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("license", text="License")
            elif openType == PACKAGE:
                self.treeView.column("#0", width=200, anchor="w")
                self.treeView["columns"] = ("vers", "descr", "license")
                self.treeView.column("vers",
                                     width=100,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("vers", text="Version")
                self.treeView.column("descr",
                                     width=400,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("descr", text="Description")
                self.treeView.column("license",
                                     width=70,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("license", text="License")
            else:
                self.treeView["columns"] = tuple()

            loadedPaths = []
            for i, filename in enumerate(self.filenames):
                if isinstance(filename, tuple):
                    if self.isRss:
                        form, date, instDoc = filename[2:5]
                    elif openType == PLUGIN:
                        name, vers, descr, license = filename[3:7]
                    elif openType == PACKAGE:
                        vers, descr, license = filename[3:6]
                    filename = filename[0]  # ignore tooltip
                    self.hasToolTip = True
                if filename.endswith("/"):
                    filename = filename[:-1]
                path = filename.split("/")
                if not self.isRss and len(
                        path) > 1 and path[:-1] in loadedPaths:
                    parent = "file{0}".format(loadedPaths.index(path[:-1]))
                else:
                    parent = ""
                node = self.treeView.insert(parent,
                                            "end",
                                            "file{0}".format(i),
                                            text=path[-1])
                if self.isRss:
                    self.treeView.set(node, "descr", form)
                    self.treeView.set(node, "date", date)
                    self.treeView.set(node, "instDoc",
                                      os.path.basename(instDoc))
                elif openType == PLUGIN:
                    self.treeView.set(node, "name", name)
                    self.treeView.set(node, "vers", vers)
                    self.treeView.set(node, "descr", descr)
                    self.treeView.set(node, "license", license)
                elif openType == PACKAGE:
                    self.treeView.set(node, "vers", vers)
                    self.treeView.set(node, "descr", descr)
                    self.treeView.set(node, "license", license)
                if self.selection == filename:
                    selectedNode = node
                loadedPaths.append(path)

        elif openType == ENTRY_POINTS:
            self.treeView.column("#0", width=200, anchor="w")
            self.treeView.heading("#0", text="Name")

            self.treeView["columns"] = ("url", )
            self.treeView.column("url", width=300, anchor="w")
            self.treeView.heading("url", text="URL")

            for fileType, fileUrl in getattr(self, "packageContainedInstances",
                                             ()):
                self.treeView.insert("",
                                     "end",
                                     fileUrl,
                                     values=fileType,
                                     text=fileUrl or urls[0][2])
            for name, urls in sorted(
                    self.taxonomyPackage["entryPoints"].items(),
                    key=lambda i: i[0][2]):
                self.treeView.insert("",
                                     "end",
                                     name,
                                     values="\n".join(url[1] for url in urls),
                                     text=name or urls[0][2])

            self.hasToolTip = True
        else:  # unknown openType
            return None
        if selectedNode:
            self.treeView.see(selectedNode)
            self.treeView.selection_set(selectedNode)

        if self.showAltViewButton:
            self.altViewButton.config(text=_("Show Files") if openType ==
                                      ENTRY_POINTS else _("Show Entries"))

    def ok(self, event=None):
        selection = self.treeView.selection()
        if len(selection) > 0:
            filename = None
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM):
                if self.multiselect:
                    filenames = []
                for _selection in selection:
                    filename = self.filenames[int(_selection[4:])]
                    if isinstance(filename, tuple):
                        if self.isRss:
                            filename = filename[4]
                        else:
                            filename = filename[0]
                    if self.multiselect:
                        filenames.append(filename)
                    else:
                        break
                if self.multiselect and filenames:
                    self.filesource.select(filenames)  # array of file names
                    self.accepted = True
                    self.close()
            elif self.openType == ENTRY_POINTS:
                epName = selection[0]
                #index 0 is the remapped Url, as opposed to the canonical one used for display
                # Greg Acsone reports [0] does not work for Corep 1.6 pkgs, need [1], old style packages
                filenames = []
                for _url, _type in self.packageContainedInstances:  # check if selection was an inline instance
                    if _type in selection:
                        if _url in self.packageContainedIXDSes:  # taxonomy package
                            filenames.extend(self.packageContainedIXDSes[_url])
                        else:  # single instance
                            filenames.append(_url)
                if not filenames:  # else if it's a named taxonomy entry point
                    for url in self.taxonomyPackage["entryPoints"][epName]:
                        filename = url[0]
                        if not filename.endswith("/"):
                            # check if it's an absolute URL rather than a path into the archive
                            if not isHttpUrl(
                                    filename
                            ) and self.metadataFilePrefix != self.taxonomyPkgMetaInf:
                                # assume it's a path inside the archive:
                                filename = self.metadataFilePrefix + filename
                        filenames.append(filename)
                if filenames:
                    self.filesource.select(filenames)
                    self.accepted = True
                    self.close()
                return
            elif self.openType in (PLUGIN, PACKAGE):
                filename = self.filenames[int(selection[0][4:])][2]
            if filename is not None and not self.multiselect and not filename.endswith(
                    "/"):
                if hasattr(self, "taxonomyPackage"):
                    # attempt to unmap the filename to original file
                    # will be mapped again in loading, but this allows schemaLocation to be unmapped
                    for prefix, remapping in self.taxonomyPackage[
                            "remappings"].items():
                        if isHttpUrl(remapping):
                            remapStart = remapping
                        else:
                            remapStart = self.metadataFilePrefix + remapping
                        if filename.startswith(remapStart):
                            # set unmmapped file
                            filename = prefix + filename[len(remapStart):]
                            break
                if self.openType in (PLUGIN, PACKAGE):
                    self.filesource.selection = filename
                else:
                    self.filesource.select(filename)
                self.accepted = True
                self.close()

    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()

    def showAltView(self, event=None):
        if self.openType == ENTRY_POINTS:
            self.loadTreeView(ARCHIVE, _("Select Entry Point"), _("File"))
        else:
            self.loadTreeView(ENTRY_POINTS, _("Select Archive File"),
                              _("File"))

    def leave(self, *args):
        self.toolTipRowId = None

    def motion(self, *args):
        tvRowId = self.treeView.identify_row(args[0].y)
        if tvRowId != self.toolTipRowId:
            text = None
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
                self.toolTipRowId = tvRowId
                if tvRowId and len(tvRowId) > 4:
                    try:
                        text = self.filenames[int(tvRowId[4:])]
                        if isinstance(text, tuple):
                            text = (text[1] or "").replace("\\n", "\n")
                    except (KeyError, ValueError):
                        pass
            elif self.openType == ENTRY_POINTS:
                try:
                    text = "{0}\n{1}".format(
                        tvRowId, "\n".join(
                            url[1] for url in
                            self.taxonomyPackage["entryPoints"][tvRowId]))
                except KeyError:
                    pass
            self.setToolTip(text)

    def setToolTip(self, text):
        self.toolTip._hide()
        if text:
            self.toolTipText.set(text)
            self.toolTip.configure(state="normal")
            self.toolTip._schedule()
        else:
            self.toolTipText.set("")
            self.toolTip.configure(state="disabled")
Exemple #8
0
class Gui(tk.Frame):
    """Main program graphical user interface"""
    def __init__(self, master=None, *args, **kwargs):
        super().__init__(master, *args, **kwargs)
        self.build_menu(), self.build()

    def build_menu(self):
        """Initializes and builds program menu bar"""
        self.top = tk.Menu(self)

        # create file menu
        self.file = tk.Menu(self.top, tearoff=False)
        self.file.add_command(label='Search',
                              accelerator='Ctrl+S',
                              command=self.search,
                              compound=tk.LEFT,
                              underline=0)
        self.file.add_separator()
        self.file.add_command(label='Exit',
                              command=self.quit_program,
                              underline=0)
        self.top.add_cascade(label='File', menu=self.file, underline=0)

        # commands: view help, about
        self.info = tk.Menu(self.top, tearoff=False)
        self.info.add_command(label='About ...',
                              command=self.view_credits,
                              compound=tk.LEFT,
                              underline=0)
        self.top.add_cascade(label='?', menu=self.info, underline=0)

    def build(self):
        """Builds main program interface"""

        # search frame
        f1 = tk.Frame()
        f1.grid(row=0, column=0)
        group = tk.LabelFrame(f1, text="Search", padx=5, pady=5, fg='brown')
        group.pack(side="top",
                   expand='yes',
                   fill='x',
                   padx=2,
                   pady=2,
                   anchor='n')
        self.entry_main = tk.Entry(group, width=73)
        self.entry_main.grid(sticky='ne')

        # results frame
        f2 = tk.Frame()
        f2.grid(row=1, column=0)
        group_2 = tk.LabelFrame(f2, text="Results", padx=5, pady=5, fg='brown')
        group_2.pack(side="top", expand='yes', fill='both', padx=2, pady=2)
        self.status = tk.Label(f2, text='ready', font=('verdana', 6, 'normal'))
        self.status.pack(anchor='se')
        self.treeview = Treeview(group_2,
                                 column=('A', 'B'),
                                 selectmode='extended',
                                 height=5)
        self.treeview.grid(row=0, column=0, sticky='w')
        self.treeview.column("#0", stretch=tk.NO, width=200)
        self.treeview.heading("#0", text='target')
        self.treeview.column("A", width=150, anchor='center')
        self.treeview.heading("A", text='technology')
        self.treeview.column("B", width=70)
        self.treeview.heading("B", text="version")
        self.sbar = tk.Scrollbar(group_2)
        self.treeview.config(yscrollcommand=self.sbar.set)
        self.sbar.config(command=self.treeview.yview)
        self.sbar.grid(column=1, row=0, rowspan=1, pady=0, sticky='ens')

        # key shortcut bindings
        self.entry_main.bind('<Return>', self.search)
        self.entry_main.bind('<Double-1>', self.search)
        self.bind_all('<Control-S>', self.search)
        self.bind_all('<Control-s>', self.search)

    def search(self, event=None):
        """Triggers a threaded technology detection scan"""
        url = self.entry_main.get()
        self.status['text'] = 'scanning...'
        Thread(target=self.scan_target, args=(url, )).start()

    def scan_target(self, url):
        """Function to detect technologies running on target and list them in
        gui treeview"""
        _id = None
        try:
            d = Detector().detect(url=url, timeout=5)
            for result in d:
                if d[result]:
                    ext = tldextract.extract(url)
                    _id = self.treeview.insert('',
                                               'end',
                                               text='.'.join(ext[:3]))
                    tech_type, software = d[result][0].get('type'), \
                                          d[result][0].get('app')
                    version = d[result][0].get('ver')

                    # assign to gui treeview
                    if not version:
                        version = 'None'
                    self.treeview.insert(_id,
                                         'end',
                                         text=tech_type,
                                         values=(software, version))
                    self.status['text'] = 'done'
                else:
                    self.status['text'] = 'No results found'

        except ValueError:
            self.status['text'] = "Invalid! Please input a full url"
        finally:
            del _id

    def view_credits(self):
        """ Opens a new window providing credits information."""

        # launch window and configure window settings
        self.win_credits = CreditsTool(self)
        self.win_credits.title('')
        self.win_credits.iconbitmap('wad/data/magnifier.ico')
        self.win_credits.geometry('+%d+%d' %
                                  (root.winfo_x() + 20, root.winfo_y() + 20))
        self.win_credits.resizable(width=False, height=False)

        # set focus on window
        self.win_credits.grab_set()
        self.win_credits.focus()

        # start mainloop
        self.win_credits.mainloop()

    @staticmethod
    def quit_program():
        """Quits main program window"""
        root.destroy()
class RefBook(Frame):

    ########
    # Opens database from provided arguments and creates and populates widgets.
    def __init__(self, master, *args, **kwargs):
        super().__init__(master)

        self._dbm = DatabaseManager(*args, **kwargs)
        self._openItems = {}
        self._openStores = {}
        self._openAttacks = {}
        self._openCreatures = {}
        self._openLocations = {}

        self._create_widgets()
        self._populate_items()
        self._populate_stores()
        self._populate_attacks()
        self._populate_creatures()
        self._populate_locations()

    ########
    # Initializes and places all GUI elements.
    def _create_widgets(self):
        self._nb = Notebook(self)

        # items
        self._itemTab = Frame(self._nb)
        self._itemTree = Treeview(self._itemTab,
                                  columns=["type", "value"],
                                  selectmode="browse",
                                  height=25)
        self._itemTree.heading("#0", text="Item", anchor=N + W)
        self._itemTree.column("#0", width=300, anchor=N + W, stretch=True)
        self._itemTree.heading("type", text="Type", anchor=N + W)
        self._itemTree.column("type", width=100, anchor=N + W)
        self._itemTree.heading("value", text="Value", anchor=N + W)
        self._itemTree.column("value", width=60, anchor=N + W)
        self._itemScroll = Scrollbar(self._itemTab,
                                     command=self._itemTree.yview)
        self._itemTree.config(yscrollcommand=self._itemScroll.set)

        self._itemTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._itemScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._itemTab, text="Items")

        # stores
        self._storeTab = Frame(self._nb)
        self._storeTree = Treeview(self._storeTab,
                                   columns=["location"],
                                   selectmode="browse",
                                   height=25)
        self._storeTree.heading("#0", text="Store", anchor=N + W)
        self._storeTree.column("#0", width=330, anchor=N + W, stretch=True)
        self._storeTree.heading("location", text="Location", anchor=N + W)
        self._storeTree.column("location", width=130, anchor=N + W)
        self._storeScroll = Scrollbar(self._storeTab,
                                      command=self._storeTree.yview)
        self._storeTree.config(yscrollcommand=self._storeScroll.set)

        self._storeTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._storeScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._storeTab, text="Stores")

        # attacks
        self._attackTab = Frame(self._nb)
        self._attackTree = Treeview(self._attackTab,
                                    columns=["id", "spell"],
                                    selectmode="browse",
                                    height=25)
        self._attackTree.heading("#0", text="Attacks", anchor=N + W)
        self._attackTree.column("#0", width=370, anchor=N + W, stretch=True)
        self._attackTree.heading("id", text="ID", anchor=N + W)
        self._attackTree.column("id", width=40, anchor=N + E)
        self._attackTree.heading("spell", text="Spell", anchor=N + W)
        self._attackTree.column("spell", width=50, anchor=CENTER)
        self._attackScroll = Scrollbar(self._attackTab,
                                       command=self._attackTree.yview)
        self._attackTree.config(yscrollcommand=self._attackScroll.set)

        self._attackTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._attackScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._attackTab, text="Attacks")

        # creatures
        self._creatureTab = Frame(self._nb)
        self._creatureTree = Treeview(self._creatureTab,
                                      columns=["hd"],
                                      selectmode="browse",
                                      height=25)
        self._creatureTree.heading("#0", text="Creatures", anchor=N + W)
        self._creatureTree.column("#0", width=420, anchor=N + W, stretch=True)
        self._creatureTree.heading("hd", text="HD", anchor=N + W)
        self._creatureTree.column("hd", width=40, anchor=N + E)
        self._creatureScroll = Scrollbar(self._creatureTab,
                                         command=self._creatureTree.yview)
        self._creatureTree.config(yscrollcommand=self._creatureScroll.set)

        self._creatureTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._creatureScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._creatureTab, text="Creatures")

        # locations
        self._locationTab = Frame(self._nb)
        self._locationTree = Treeview(self._locationTab,
                                      selectmode="browse",
                                      height=25)
        self._locationTree.heading("#0", text="Locations", anchor=N + W)
        self._locationTree.column("#0", width=460, anchor=N + W, stretch=True)
        self._locationScroll = Scrollbar(self._locationTab,
                                         command=self._locationTree.yview)
        self._locationTree.config(yscrollcommand=self._locationScroll.set)

        self._locationTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._locationScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._locationTab, text="Locations")

        self._nb.grid(row=0, column=0, sticky=N + W + S + E)

        # bindings
        self._itemTree.bind("<Double-Button-1>", self._item_on_double_click)
        self._storeTree.bind("<Double-Button-1>", self._store_on_double_click)
        self._attackTree.bind("<Double-Button-1>",
                              self._attack_on_double_click)
        self._creatureTree.bind("<Double-Button-1>",
                                self._creature_on_double_click)
        self._locationTree.bind("<Double-Button-1>",
                                self._location_on_double_click)

    ########
    # Populates item list.
    def _populate_items(self):
        self._itemList = self._dbm.get_item_list()

        allItems = self._itemTree.get_children()
        for item in allItems:
            self._itemTree.delete(item)
        self._itemImgs = []
        if self._dbm == None:
            return
        for entry in self._itemList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [BaseView.TYPE_MAP[entry["type"]], entry["value"]]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._itemImgs.append(img)
            self._itemTree.insert("", END, image=img, text=name, values=fields)

    ########
    # Populates store list.
    def _populate_stores(self):
        self._storeList = self._dbm.get_store_list()

        allStores = self._storeTree.get_children()
        for store in allStores:
            self._storeTree.delete(store)
        self._storeImgs = []
        if self._dbm == None:
            return
        for entry in self._storeList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [entry["location"]]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._storeImgs.append(img)
            self._storeTree.insert("",
                                   END,
                                   image=img,
                                   text=name,
                                   values=fields)

    ########
    # Populates attack list.
    def _populate_attacks(self):
        self._attackList = self._dbm.get_attack_list()

        allAttacks = self._attackTree.get_children()
        for attack in allAttacks:
            self._attackTree.delete(attack)
        self._attackImgs = []
        if self._dbm == None:
            return
        for entry in self._attackList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [entry["id"], "✔" if entry["isSpell"] else ""]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._attackImgs.append(img)
            self._attackTree.insert("",
                                    END,
                                    image=img,
                                    text=name,
                                    values=fields)

    ########
    # Populates creature list.
    def _populate_creatures(self):
        self._creatureList = self._dbm.get_creature_list()

        allCreatures = self._creatureTree.get_children()
        for creature in allCreatures:
            self._creatureTree.delete(creature)
        self._creatureImgs = []
        if self._dbm == None:
            return
        for entry in self._creatureList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [str(entry["hd"])]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._creatureImgs.append(img)
            self._creatureTree.insert("",
                                      END,
                                      image=img,
                                      text=name,
                                      values=fields)

    ########
    # Populates location list.
    def _populate_locations(self):
        self._locationList = self._dbm.get_location_list()

        allLocations = self._locationTree.get_children()
        for location in allLocations:
            self._locationTree.delete(location)
        self._locationImgs = []
        if self._dbm == None:
            return
        for entry in self._locationList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            self._locationImgs.append(img)
            self._locationTree.insert("", END, image=img, text=name)

    ########
    # Callback for double clicking in item treeview.
    def _item_on_double_click(self, *args, **kwargs):
        if len(self._itemTree.selection()) == 0:
            return
        self.show_item(self._itemList[self._itemTree.index(
            self._itemTree.selection())]["name"])

    ########
    # Callback for double clicking in store treeview.
    def _store_on_double_click(self, *args, **kwargs):
        if len(self._storeTree.selection()) == 0:
            return
        curr = self._storeList[self._storeTree.index(
            self._storeTree.selection())]
        self.show_store(curr["name"], curr["location"])

    ########
    # Callback for double clicking in attack treeview.
    def _attack_on_double_click(self, *args, **kwargs):
        if len(self._attackTree.selection()) == 0:
            return
        self.show_attack(self._attackList[self._attackTree.index(
            self._attackTree.selection())]["id"])

    ########
    # Callback for double clicking in creature treeview.
    def _creature_on_double_click(self, *args, **kwargs):
        if len(self._creatureTree.selection()) == 0:
            return
        self.show_creature(self._creatureList[self._creatureTree.index(
            self._creatureTree.selection())]["name"])

    ########
    # Callback for double clicking in location treeview.
    def _location_on_double_click(self, *args, **kwargs):
        if len(self._locationTree.selection()) == 0:
            return
        self.show_location(self._locationList[self._locationTree.index(
            self._locationTree.selection())]["name"])

    ########
    # Shows a full item in a new window.
    def show_item(self, name):
        if name in self._openItems.keys():
            # TODO: make this cleaner
            try:
                self._openItems[name].lift()
                self._openItems[name].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        itemView = ItemView(newWindow, self._dbm.get_item(name), refBook=self)
        itemView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openItems[name] = newWindow

    ########
    # Shows a full store in a new window.
    def show_store(self, name, location):
        key = (name, location)
        if key in self._openStores.keys():
            # TODO: make this cleaner
            try:
                self._openStores[key].lift()
                self._openStores[key].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        storeView = StoreView(newWindow,
                              self._dbm.get_store(name, location),
                              refBook=self)
        storeView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openStores[key] = newWindow

    ########
    # Shows a full attack in a new window.
    def show_attack(self, attackId):
        if attackId in self._openAttacks.keys():
            # TODO: make this cleaner
            try:
                self._openAttacks[attackId].lift()
                self._openAttacks[attackId].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        attack = self._dbm.get_attack(attackId)
        newWindow = Toplevel(self)
        attackView = AttackView(newWindow,
                                self._dbm.get_attack(attackId),
                                refBook=self)
        attackView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title("{} ({})".format(attack["name"], attack["id"]))
        newWindow.lift()
        newWindow.focus_set()
        self._openAttacks[attackId] = newWindow

    ########
    # Shows a full creature in a new window.
    def show_creature(self, name):
        if name in self._openCreatures.keys():
            # TODO: make this cleaner
            try:
                self._openCreatures[name].lift()
                self._openCreatures[name].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        creatureView = CreatureView(newWindow,
                                    self._dbm.get_creature(name),
                                    refBook=self)
        creatureView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openCreatures[name] = newWindow

    ########
    # Shows a full location in a new window.
    def show_location(self, name):
        if name in self._openLocations.keys():
            # TODO: make this cleaner
            try:
                self._openLocations[name].lift()
                self._openLocations[name].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        locationView = LocationView(newWindow,
                                    self._dbm.get_location(name),
                                    refBook=self)
        locationView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openLocations[name] = newWindow
Exemple #10
0
update_btn.grid(row=0, column=2)

clear_btn = Button(frame_btns, text='Clear', width=12, command=clear_text)
clear_btn.grid(row=0, column=3)

#frame 3 contact list
frame_router = Frame(app)
frame_router.grid(row=2, column=0, columnspan=4, rowspan=6, pady=20, padx=20)

columns = ['id', 'Name']
router_tree_view = Treeview(frame_router, columns=columns, show="headings")
router_tree_view.column("id", width=30)
for col in columns[1:]:
    router_tree_view.column(col, width=450)
    router_tree_view.heading(col, text=col)
router_tree_view.bind('<<TreeviewSelect>>', select_contact)
router_tree_view.pack(side="left", fill="y")
scrollbar = Scrollbar(frame_router, orient='vertical')
scrollbar.configure(command=router_tree_view.yview)
scrollbar.pack(side="right", fill="y")
router_tree_view.config(yscrollcommand=scrollbar.set)

app.title('Contacts')
app.geometry('525x575')

# Populate data
populate_list()

# Start program
app.mainloop()
Exemple #11
0
class Gui(Frame):
    __slots__ = ('selectedbox','desiredbox','logger','clidisp','ls','tgtbox',\
                 'thread','dir','running','startb','cliententry','commandlist','clientnum',
                 'scale'\
                     )

    def __init__(self, master):
        Frame.__init__(self, master)
        xpos = 0.05
        self.running = 0  #not listening

        self.debug = BooleanVar()
        self.debug.set(False)

        self.frame = Frame(colormap='new')
        self.frame.place(relx=xpos, rely=0.67)
        self.startb = Button(self.frame, text = "Start Server", command = self.startc,height=2, width=20,\
                             bg='#90ee90')
        self.startb.pack(side=LEFT, anchor=S)

        self.connectionl = Label(self.frame,
                                 text="OFF.",
                                 height=2,
                                 bg='#ff5f5f')

        self.connectionl.pack(side=LEFT, anchor=E, expand=YES)
        self.expertmode = BooleanVar()
        self.expertmode.set(False)
        self.showexpert = Checkbutton(text='Expert Mode',
                                      variable=self.expertmode,
                                      command=self.placeframe)
        self.showexpert.place(relx=xpos, rely=0.74)

        self.framecommand = Frame()

        self.commandlabel = Label(self.framecommand,
                                  text='Command to Client: ')
        self.commandtext = Entry(self.framecommand, width=15)
        self.cliententry = Entry(self.framecommand, width=10)
        self.addrlabel = Label(self.framecommand, text='Client Box ID: ')
        self.sendbutton=Button(self.framecommand,text='Send Command\nto Client', width=12,height=4\
                               ,command=self.send_command)

        self.tgtbox = None

        self.logoframe = Frame()
        self.logoframe.place(relx=xpos, rely=0.04)
        self.logo = PhotoImage(file=os.path.join('images', 'logo2.png'))
        self.logolabel = Label(self.logoframe, image=self.logo)
        self.logolabel.pack()

        self.cliframe = Frame(colormap='new')
        self.cliframe.place(relx=0.4, rely=0.1)

        #        self.condisp=Listbox (self.cliframe,width=80,height=12)
        self.scrollbartop = Scrollbar(self.cliframe)
        self.clidisp = Treeview(self.cliframe, height=12)
        self.clidisp['show'] = 'headings'
        self.clidisp['columns'] = ('boxid', 'ip')
        self.clidisp.heading('ip', text='IP')
        self.clidisp.heading('boxid', text='Box ID')
        self.clidisp.column('boxid', width=152)
        self.clidisp.column('ip', width=490)
        self.clidisp.pack(side=LEFT, fill=Y)

        #        self.condisp.pack(side=LEFT,fill=Y)
        self.scrollbartop.pack(side=RIGHT, fill=Y)
        self.scrollbartop.config(command=self.clidisp.yview)
        self.clidisp.config(yscrollcommand=self.scrollbartop.set)

        self.conntitle = Label(text='Connected Clients↓ ')
        self.conntitle.place(relx=0.4, rely=0.05)
        self.cdframe = Frame(colormap='new')
        self.cdframe.place(relx=0.7, rely=0.05)
        self.numtitle=Label(self.cdframe,text='Total Connected Clients: ',\
                            bg='#ff5f5f')


        self.clientnum=Label(self.cdframe,text=str(len(self.clidisp.get_children())),\
                             bg='#ff5f5f',font=("", 16))

        self.numtitle.pack(side=LEFT)
        self.clientnum.pack(side=LEFT)

        self.checkdebug = Checkbutton(text='Debug Mode', variable=self.debug)
        self.checkdebug.place(relx=0.6, rely=0.5)
        self.logtitile = Label(text='Logs↓ ')
        self.logtitile.place(relx=0.4, rely=0.5)
        self.scrolltext = Frame(colormap='new')
        self.scrolltext.place(relx=0.4, rely=0.55)

        if sys.platform.startswith('win'):
            self.logger = Text(self.scrolltext,
                               state=DISABLED,
                               height=16,
                               width=71)
        else:
            self.logger = Text(self.scrolltext,
                               state=DISABLED,
                               height=15,
                               width=64)

        self.scrollbar = Scrollbar(self.scrolltext)
        self.logger.pack(side=LEFT, fill=Y)
        self.scrollbar.pack(fill=BOTH, expand=True)
        self.scrollbar.config(command=self.logger.yview)
        self.logger.config(yscrollcommand=self.scrollbar.set)

        self.logger.tag_configure(0,
                                  background="#27d827",
                                  foreground='#d82780')
        self.logger.tag_configure(1, background="#58a758")
        self.logger.tag_configure(2, background="#4bb543")
        self.logger.tag_configure(3,
                                  background="#000000",
                                  foreground='#00aecd')
        self.logger.tag_configure(4, background="#ffd8ff")
        self.logger.tag_configure(5, background="#ffc4ff")
        self.logger.tag_configure(6, background="#ff89ff")
        self.logger.tag_configure(7, background="#ff9d9d")
        self.logger.tag_configure(8, background="#ff6262")
        self.logger.tag_configure(9,
                                  background="#d80000",
                                  foreground='#00d8d8')

        self.framehp = Frame()

        self.framehp.place(relx=xpos, rely=0.17)
        self.framehost = Frame(self.framehp)
        self.frameport = Frame(self.framehp)
        self.invalidtext = Label(self.framehost,
                                 text=' ✘ Please Enter a number \nfrom 0-254',
                                 foreground='#c40000')
        self.invalidtextport = Label(
            self.frameport,
            text=' ✘ Please Enter a number \nfrom 1-65535',
            foreground='#c40000')
        self.framehost.pack(side=TOP, anchor=W)
        self.frameport.pack(side=TOP, anchor=W)

        self.hostnum1 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum1.insert(INSERT, '0')
        self.hostnum2 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum2.insert(INSERT, '0')
        self.hostnum3 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum3.insert(INSERT, '0')
        self.hostnum4 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum4.insert(INSERT, '0')
        self.dot1 = Label(self.framehost, text='.')
        self.dot2 = Label(self.framehost, text='.')
        self.dot3 = Label(self.framehost, text='.')

        self.hostlabel = Label(self.framehost, text='Host  :')

        self.portnum=intEnt(self.frameport,width=6,\
                            maxlen=5,minval=0,maxval=65536,label=self.invalidtextport)

        self.portlabel = Label(self.frameport, text='Port  :')

        self.portnum.insert(INSERT, '10086')
        self.hostlabel.pack(side=LEFT, pady=3)
        self.hostnum1.pack(side=LEFT, pady=3)
        self.dot1.pack(side=LEFT, pady=3)
        self.hostnum2.pack(side=LEFT, pady=3)
        self.dot2.pack(side=LEFT, pady=3)
        self.hostnum3.pack(side=LEFT, pady=3)
        self.dot3.pack(side=LEFT, pady=3)
        self.hostnum4.pack(side=LEFT, pady=3)
        self.portlabel.pack(side=LEFT, pady=3)
        self.portnum.pack(side=LEFT, pady=3)

        self.errhost = Label(text='Number must between 0 and 255')
        self.errport = Label(text='Number must between 1 and 65535')

        self.framets = Frame(colormap='new')
        self.framets.place(relx=xpos, rely=0.27)
        self.timespan = IntVar()
        self.scale=Scale(self.framets,variable=self.timespan, orient=HORIZONTAL, \
                         from_=10, to=60,bg='#dcdcdc', length=230)
        self.scale.set(60)
        self.tslabel = Label(self.framets, text='Time per File (seconds):')
        self.tslabel.pack(side=TOP, anchor=W)
        self.scale.pack(side=LEFT)

        self.frame2 = Frame(colormap='new')
        self.frame2.place(relx=xpos, rely=0.5)
        self.outbtn = Button(text='Select Directory',
                             command=self.Folder,
                             bg='#cfcfcf',
                             width=20)
        self.dir = os.path.join('data', '')
        self.outbtn.place(relx=xpos, rely=0.4)
        self.dirlabel = Label(self.frame2, text='↓ Curret Directory ')
        self.dirtext = Label(self.frame2,
                             text=self.dir,
                             wraplength=400,
                             justify=LEFT)
        self.dirlabel.pack(side=TOP, anchor=W, pady=5)
        self.dirtext.pack(side=LEFT)

        self.radioframe = Frame(colormap='new')
        self.v = BooleanVar()
        explain = Label(self.radioframe, text='Save File As: ').pack(side=LEFT,
                                                                     anchor=W)
        self.rb1 = Radiobutton(self.radioframe,
                               text=".mseed",
                               variable=self.v,
                               value=False)
        self.rb1.pack(side=LEFT, anchor=W)
        self.rb2 = Radiobutton(self.radioframe,
                               text=".dat",
                               variable=self.v,
                               value=True)
        self.rb2.pack(side=LEFT, anchor=W)

        self.radioframe.place(relx=xpos, rely=0.45)
        self.sendbutton.pack(side=RIGHT,
                             anchor=SE,
                             padx=20,
                             pady=10,
                             expand=YES)
        self.addrlabel.pack(side=TOP, anchor=NW)
        self.cliententry.pack(side=TOP, anchor=NW)
        self.commandlabel.pack(side=TOP, anchor=NW)
        self.commandtext.pack(side=TOP, anchor=NW)
        self.bytestosend = bytearray(b'')

        self.selectedbox = None
        self.desiredbox = None
        self.headlen = 24
        self.commandlist = {
            'command1': b'\x55\xaa\x55',
            'command2': b'\xaa\x55\xaa'
        }
        return

    def send_command(self):

        box = self.cliententry.get()
        self.tgtbox = box
        self.showtext(
            '{} Command send to Box# {}'.format(self.commandtext.get(), box),
            2)
        return

    def check_entval(self):

        self.hostcheck=all((self.hostnum1.check(),self.hostnum2.check(),\
                            self.hostnum3.check(),self.hostnum4.check()))
        self.portcheck = self.portnum.check()

        if self.hostcheck:
            self.errhost.place(relx=0.4, rely=0.4)
        else:
            self.errhost.place_forget()
        if self.portcheck:
            self.errport.place(relx=0.4, rely=0.4)
        else:
            self.errport.place_forget()
        return

    def socket_thread(self):

        host = self.check_ip()
        port = self.check_port()
        if (host and port):

            self.showtext("thread started.. ", 0)
            self.ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.ls.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            try:
                self.ls.bind((host, port))

            except OSError as err:
                self.enableedit()
                self.showtext("OS error: {0} ".format(err), 9)
                self.showtext(
                    'Please Close Application using Port: %s ' % port, 9)
                self.showtext('Server Stopped ', 7)
                self.connectionl.configure(text="OFF.", bg='#ff5f5f')
                raise OSError('Port Being Used')
                return

            self.running = 1
            sleep(0.2)

            try:
                self.showtext("Server listening on port %s " % port, 1)
                while self.running != 0:
                    self.ls.listen(5)
                    self.ls.setblocking(1)
                    self.connectionl.configure(text="RUNNING!", bg='#4bb543')
                    (conn, addr) = self.ls.accept()
                    self.showtext("client is at "+ str(addr[0])+ \
                                       " on port "+str(addr[1]),2)
                    newthread = Thread(target=self.run_server,
                                       args=(conn, addr))
                    newthread.start()
                    newthread.join(1)

            except (Exception) as e:
                self.enableedit()
                self.showtext("Connect exception: " + str(e) + '', 9)
                self.connectionl.configure(text="OFF.", bg='#ff5f5f')
                self.forcestop()
                return

        return

    def run_server(self, conn, addr):
        head = b'\x34\x37\x36\x35'
        NotInserted = True
        i = 0
        counter = 0
        data_saved = bytearray(b'')
        seed_data = []

        recv_data = bytearray(b'')
        data_recv = bytearray(b'')
        timeNotpresent = True
        SendClientInfo = False
        st = Stream([])

        self.showtext("connected to {}, {}".format(conn, addr), 3)
        self.showtext('Data From: {}'.format(addr), 3)

        try:

            while self.running != 0:

                recv_data = bytearray(conn.recv(524288))
                Permission = False
                data_recv += recv_data

                if len(data_recv) >= 15000:

                    start = data_recv.find(b'\x32\x34\x56\x67')
                    end = data_recv.rfind(b'\x32\x34\x56\x67')
                    check = (len(data_recv[start:end]) - self.headlen) % 4

                    if start == end:

                        data_recv = data_recv[start:]

                    elif end > start and (check) % 4 == 0:

                        data_buffer = data_recv[start:end]
                        data_recv = data_recv[end:]
                        Permission = True

                    elif end > start:

                        data_buffer = data_recv[start:end - check]
                        data_recv = data_recv[end:]
                        Permission = True

                if (Permission and len(data_buffer) > 12):

                    connect_start = time()  # reset timeout time

                    if i == 0:
                        i += 1
                        data_buffer.clear()
                        Permission = False
                        continue

                    ID = str(data_buffer[4:7].decode())

                    if (ID == 'SEL'):

                        children = self.clidisp.get_children()
                        # self.values=b'\xff\xfe\xfd\xfc\xfb'
                        self.values = bytearray(b'')

                        for child in children:
                            a = list(self.clidisp.item(child).values())
                            a = a[2][0]
                            if isinstance(a, int):
                                thing = struct.pack('>H', a)
                                self.values += thing

                        conn.sendall(self.bytestosend + head + self.values)
                        # self.bytestosend.clear()
                        self.bytestosend = bytearray(b'')

                        if NotInserted:
                            address = ('{}:{}'.format(addr[0], addr[1]))
                            self.clidisp.insert('',
                                                'end',
                                                'box' + ID,
                                                values=(ID, address))
                            #                        self.clientnum.config(text=str(len(self.clidisp.get_children())))
                            NotInserted = False

                        if (data_buffer[7:9] != b'\x99\x99'):
                            self.desiredbox = struct.unpack(
                                '>H', data_buffer[7:9])[0]

                    else:
                        # conn.settimeout(120)
                        conn.sendall(data_buffer[0:7])

                        #                       print(data_buffer[0:7])

                        if int(ID) == self.desiredbox:
                            self.bytestosend.clear()
                            self.bytestosend += data_buffer

                        if (self.tgtbox == ID):

                            command = self.commandtext.get()
                            commandtosend = self.commandlist[command]
                            conn.sendall(commandtosend)
                            counter += 1

                            if counter >= 5:
                                self.tgtbox = None
                                continue
                            if counter > 10:
                                self.tgtbox = None
                                break

                        if NotInserted:
                            address = ('{}:{}'.format(addr[0], addr[1]))
                            try:
                                self.clidisp.insert('',
                                                    'end',
                                                    'box{}'.format(ID),
                                                    values=(ID, address))
                            except:
                                pass

    #                        self.clientnum.config(text=str(len(self.clidisp.get_children())))
                            NotInserted = False
                            self.showtext('Hello, I am Box# {}'.format(ID), 2)
                        self.checkcolor()
                        if timeNotpresent:
                            try:
                                year = struct.unpack('>1H', data_buffer[7:9])
                                year = int(year[0])
                                month = int(
                                    struct.unpack('>1B', data_buffer[9:10])[0])
                                day = int(
                                    struct.unpack('>1B',
                                                  data_buffer[10:11])[0])
                                hour = int(
                                    struct.unpack('>1B',
                                                  data_buffer[11:12])[0])
                                minute = int(
                                    struct.unpack('>1B',
                                                  data_buffer[12:13])[0])
                                second = int(
                                    struct.unpack('>1B',
                                                  data_buffer[13:14])[0])
                                starttime = datetime(year, month, day, hour,
                                                     minute, second)

                            except:
                                self.showtext(
                                    'Invalid Time in box# {}.. Using Computer UTC\
                                                time instead'.format(ID), 7)
                                starttime = datetime.utcnow()
                                timeNotpresent = False

                        data_buffer = bytearray(data_buffer[self.headlen:])

                        if self.v.get():
                            if timeNotpresent:
                                fn = starttime.strftime("%Y%m%d%H%M%Ss")
                                timeNotpresent = False

                            data_saved += data_buffer

                            if len(data_saved) >= 12000 * self.timespan.get():
                                #                            self.showtext('Time Check--> '+str(starttime),2,self.debug.get())
                                self.showtext(
                                    '{} Writing Original Files'.format(addr),
                                    2, self.debug.get())
                                with open(
                                        os.path.join(self.dir, str(ID),
                                                     fn + '.dat'), 'wb') as f:
                                    f.write(data_saved)
                                data_saved.clear()
                                timeNotpresent = True

                        else:

                            unpacked_display_data = np.array(
                                unpack(data_buffer))
                            if max(unpacked_display_data) > 10e10:
                                data_buffer.clear()
                                Permission = False
                                self.showtext(
                                    'Box {} Have corrupted Data'.format(ID), 7)
                                seed_data.extend(
                                    np.zeros(len(unpacked_display_data)))
                                continue

                            # seed_data.extend(unpacked_display_data)

                            # if len(seed_data) >=3000*self.timespan.get():
                            #     self.showtext('{} Writing miniseed Files'.format(addr),2,self.debug.get())
                            #     writeseed(np.array(seed_data[:3000*self.timespan.get()]),\
                            #               starttime,ID,self.dir)
                            #     seed_data=seed_data[3000*self.timespan.get():]
                            #     timeNotpresent=True

                            tempst=trace_gen(unpacked_display_data,\
                                              starttime,ID)

                            st += tempst

                            if (len(st) >= int(3 * self.timespan.get())):

                                self.showtext(
                                    '{} Writing mini-seed Files'.format(addr),
                                    2, self.debug.get())
                                st.merge(method=1, fill_value='interpolate')
                                # st.merge(method=-1)
                                writestream(st, ID, self.dir)
                                st = Stream([])

                    data_buffer.clear()
                    Permission = False

                    if (self.running == 0) or (time() - connect_start > 60):
                        self.showtext("No Data! Closing Connections!", 9)
                        # self.clidisp.delete('box'+str(ID))
                        break

        except (Exception) as e:
            # we can wait on the line if desired
            self.showtext("socket error: " + repr(e), 9)

        finally:

            self.showtext("Client at {} disconnected...".format(addr), 3)
            SendClientInfo = False
            try:
                self.clidisp.delete('box{}'.format(ID))
                conn.shutdown(socket.SHUT_RDWR)
            except:
                pass
            self.showtext("closing connection on Box# {}".format(ID), 5)
            conn.close()
            self.showtext("connection closed on Box# {}".format(ID), 4)
            self.tgtbox = None
            counter = 0
            self.checkcolor()
            return

    def close_sequence(self, conn, addr, ID=None):

        try:
            self.clidisp.delete('box{}'.format(ID))
            self.forcestop()
        except:
            pass

        self.checkcolor()
        return

    def startc(self):

        if self.running == 0:

            self.disableedit()
            self.connectionl.configure(text="INITIALIZING!", bg='#ffffaa')
            self.size = 1000 * 3 * int(self.timespan.get())
            self.scale.config(state='disabled', bg='#3f3f3f', fg='#fafafa')
            self.showtext("Starting Server ", 0)
            self.thread = Thread(target=self.socket_thread)
            self.thread.start()

            self.startb.configure(bg='#ff276f',
                                  text="Stop Server",
                                  command=self.stopc)

        else:
            self.showtext("Server already started. ", 8)
            return
        return

    def stopc(self):

        self.enableedit()
        self.scale.config(state='active', bg='#dcdcdc', fg='#000000')

        if self.running:
            self.forcestop(Close=True)
            self.showtext("stopping thread... ", 7)
            sleep(1)
            self.clidisp.delete(*self.clidisp.get_children())
            self.checkcolor()
            self.connectionl.configure(text="OFF.", bg='#ff5f5f')
            self.running = 0
            self.thread.join(1)

        try:
            raise KeyboardInterrupt('Server Terminated Due to user Action')
        except KeyboardInterrupt:
            self.showtext('Server Terminated Due to user Action', 7)
            return
        else:
            self.showtext("Server not running", 7)
        return

    def check_ip(self):

        try:
            if int(self.hostnum1.get()) > 255:
                showerror(
                    "Error",
                    "First number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0
            elif int(self.hostnum2.get()) > 255:
                showerror(
                    "Error",
                    "Second number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0

            elif int(self.hostnum3.get()) > 255:
                showerror(
                    "Error",
                    "Third number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0

            elif int(self.hostnum4.get()) > 255:

                showerror(
                    "Error",
                    "Forth number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0

            else:
                return '{}.{}.{}.{}'.format (self.hostnum1.get(),self.hostnum2.get(),\
                  self.hostnum3.get(),self.hostnum4.get())
        except:
            showerror(
                "Error",
                "Please make sure whole numbers are entered in host section")
            self.showtext('Server Stopped ', 7)
            return 0

    def check_port(self):

        try:

            if 65536 < int(self.portnum.get()):

                showerror(
                    "Error",
                    "Please enter a whole number between 1 and 65535 in Port section"
                )
                self.showtext('Server Stopped ', 7)
            else:
                return int(self.portnum.get())

        except:

            showerror(
                "Error",
                "Please make sure whole numbers are entered in port section")
            self.showtext('Server Stopped ', 7)

            return 0

    def Folder(self):

        targetdir = askdirectory()

        if targetdir:
            self.dirtext.config(text=targetdir)
            self.dir = targetdir
        return

    def checkcolor(self):

        if len(self.clidisp.get_children()) > 0:

            self.numtitle.config(text='Total Connected Clients: ',\
                        bg='#afffbf')

            self.clientnum.config(text=str(len(self.clidisp.get_children())),\
                         bg='#afffbf',font=("", 16))
        else:

            self.numtitle.config(text='Total Connected Clients: ',\
                        bg='#ff5f5f')

            self.clientnum.config(text=str(len(self.clidisp.get_children())),\
                         bg='#ff5f5f',font=("", 16))
        return

    def placeframe(self):

        if self.expertmode.get():
            showwarning("Warning","Command in Expert Mode can permnantly " \
                               'shutdown selected device(s)')
            self.framecommand.place(relx=0.05, rely=0.79)

        else:

            self.framecommand.place_forget()

        return

    def showtext(self, text, colorcheck, DEBUG=True):

        with open('logs.txt', 'a+') as f:
            f.write(gettime() + text + '\n')

        if DEBUG:
            self.logger.config(state=NORMAL)
            self.logger.insert(END, gettime() + text + '\n', colorcheck)
            self.logger.see('end')
            self.logger.config(state=DISABLED)
            return
        return

    def forcestop(self, Close=False):
        self.startb.configure(bg='#90ee90',
                              text="Start Server",
                              command=self.startc)
        try:
            self.ls.shutdown(socket.SHUT_RDWR)
        except:
            pass
        if Close:
            try:
                self.ls.close()
            except:
                pass
        return

    def enableedit(self):

        self.portnum.configure(state='normal')
        self.hostnum1.configure(state='normal')
        self.hostnum2.configure(state='normal')
        self.hostnum3.configure(state='normal')
        self.hostnum4.configure(state='normal')
        self.rb1.configure(state='normal')
        self.rb2.configure(state='normal')
        self.outbtn.configure(state='normal')
        return

    def disableedit(self):

        self.portnum.configure(state='disable')
        self.hostnum1.configure(state='disable')
        self.hostnum2.configure(state='disable')
        self.hostnum3.configure(state='disable')
        self.hostnum4.configure(state='disable')
        self.rb1.configure(state='disable')
        self.rb2.configure(state='disable')
        self.outbtn.configure(state='disable')
        return
Exemple #12
0
class TestprogramPane(Labelframe):
    '''
    classdocs
    '''
    def __init__(self, master, tp=None, name='No TP Loaded'):
        '''
        Constructor
        '''
        Labelframe.__init__(self, master)
        self.name = name
        self.tp = tp
        self.tree = Treeview(self)
        self.tree.pack(fill=BOTH, expand=True)
        self.config(width=200,
                    height=200,
                    relief=RIDGE,
                    text='Test Program',
                    padding=10)
        self.tree.bind('<<TreeviewSelect>>', self.show_params)
        self.param_view = Labelframe(self)
        self.pins_view = Labelframe(self)
        self.params = {}
        self.pins = {}
        self.load()

    def load(self):
        self.tree.delete(*self.tree.get_children())
        if (self.tp == None):
            self.tree.insert("", 'end', 'Default', text=self.name)
        else:
            self.populate(self.tp.testtree)

    def show_params(self, event):
        self.param_view.destroy()
        if (self.params.get(self.tree.selection()[0], None) != None):
            self.param_view = Labelframe(self)
            self.load_params(self.param_view, self.tree.selection()[0])
            self.param_view.config(text='Test Parameters')
            self.param_view.pack(fill=BOTH, expand=True)

    def populate(self, tp):
        for element in tp.iter():
            if (element.tag == 'TestRef'):
                self.tree.insert("",
                                 'end',
                                 element.get("name"),
                                 text=element.get("name"),
                                 open=True)
            else:
                self.tree.insert(element.getparent().get("name"),
                                 'end',
                                 element.get("name"),
                                 text=element.get("name"),
                                 open=True)
                if (element.tag == 'Test'):
                    self.params[element.get("name")] = {
                        'delay': element.get('delay'),
                        'force': element.get('force'),
                        'lolim': element.get('lolim'),
                        'hilim': element.get('hilim'),
                        'pinref': element.get('pinref'),
                        'testtype': element.get('testtype')
                    }

    def fetch_pins(self, tp, pinref):
        for element in tp.iter():
            if (element.get("name") == pinref):
                self.pins[element.get("name")] = {
                    'pintype': element.get("pintype"),
                    'pins': []
                }
            else:
                if (element.tag == 'Pin'
                        and element.getparent().get("name") == pinref):
                    self.pins[pinref].get('pins').append(element.get("name"))
#

    def load_params(self, master, test):
        master.config(text=test)
        self.param_tree = Treeview(master)
        self.param_tree.pack(fill=BOTH, expand=True)
        self.param_tree.heading('#0', text='Parameter')
        self.param_tree.config(columns=('value'))
        self.param_tree.column('value', width=100)
        self.param_tree.heading('value', text='Value')

        self.param_tree.insert('',
                               'end',
                               'delay',
                               text='DELAY',
                               values=self.params.get(test).get('delay'))
        self.param_tree.insert('',
                               'end',
                               'force',
                               text='FORCE',
                               values=self.params.get(test).get('force'))
        self.param_tree.insert('',
                               'end',
                               'lolim',
                               text='LOLIM',
                               values=self.params.get(test).get('lolim'))
        self.param_tree.insert('',
                               'end',
                               'hilim',
                               text='HILIM',
                               values=self.params.get(test).get('hilim'))
        self.param_tree.insert('',
                               'end',
                               'pinref',
                               text='PINREF',
                               values=self.params.get(test).get('pinref'))
        self.param_tree.insert('',
                               'end',
                               'testtype',
                               text='TESTTYPE',
                               values=self.params.get(test).get('testtype'))
        if self.pins_view: self.pins_view.destroy()
        self.pins_view = Labelframe(self)
        self.param_tree.bind('<<TreeviewSelect>>', self.show_pins)

    def show_pins(self, event):
        self.pins_view.destroy()
        self.pins_view = Labelframe(self)
        pinref = self.param_tree.item(self.param_tree.selection()[0],
                                      "value")[0]
        self.fetch_pins(self.tp.pintree, pinref)
        if (self.pins.get(pinref, None) != None):
            self.pins_view = Labelframe(self)
            self.load_pins(self.pins_view, pinref)
            self.pins_view.config(text='Pin Parameters')
            self.pins_view.pack(fill=BOTH, expand=True)

    def load_pins(self, master, pinref):
        pins_tree = Treeview(master)
        pins_tree.pack(fill=BOTH, expand=True)
        pins_tree.heading('#0',
                          text=(next(iter(self.pins)), ' PinType: ',
                                self.pins.get(pinref).get('pintype')))
        for p in self.pins.get(pinref).get('pins'):
            pins_tree.insert('', 'end', p, text=p)
class Windview:
    def __init__(self,root):
        self.root = root
        self.root.config(bg="#2c2f33")
        self.root.title("Portal")
        self.root.geometry("1220x720")
        self.root.iconbitmap('Medical-Management/icone.ico')
        self.root.resizable(0, 0)
 #=============================================================================================================        
        self.frame_left = Frame(self.root, width=260, height=720, bg="#23272a")
        self.frame_left.place(x=0,y=0)
        
        self.clck = Label(self.root,text="",font='Helvetica 14',fg="white",bg="#1e2124")
        self.clck.place(x=0, y=20,width=260,height=30) 
        self.update_clock()
                        
        self.label3 = Label(root, text='All work by mr-p-oliveira (⌐■_■), 2021',font='Helvetica 7',
                    fg="#D0D3D4",bg="#1e2124")
        self.label3.place(x=0 ,y=700, width=260, height=22)
        
        self.label2 = Label(root,font='Helvetica 7',
                    fg="#D0D3D4",bg="#1e2124")
        self.label2.place(x=260 ,y=700, width=960, height=22)        
        
        self.label = Label(root, text='Selected',font='Helvetica 8',
                            fg="#D0D3D4",bg="#1e2124")
        self.label.place(x=0,y=87,width=260,height=13)
        
        self.lf_lbl = Label(root,text="View",font='Helvetica 12',fg="white", bg="#005042").place(x=0,y=100,width=260,height=55)    
 #======================================================================================================================         
        self.but_ex = Button(root,text="Exit",font='Helvetica 7',width=10,fg="white", bg="#2c2f33",relief='flat',command=self.ExitApp).place(x=1150,y=700)
        self.bck_btn = Button(root,text="Back",font='Helvetica 12',width=12,fg="white", bg="#005042",command=self.back_win).place(x=1050,y=650)  
        self.see_btn = Button(root,text="See all",font='Helvetica 12',width=12,fg="white", bg="#005042",command=self.allreg_win).place(x=925,y=650) 
 #======================================================================================================================
        i = 0
        db.connect()
        
        self.tree = Treeview(root, columns=("NHS","Social", "Gender", "Blood", "Allergies","Phone", "Doctor"),show='headings', selectmode="extended")
        headings=('NHS','Social','Gender','Blood', 'Allergies','Phone','Doctor')
        sq2l = ("SELECT * FROM pat_reg")
        db_cursor.execute(sq2l)
        for j in range(len(headings)):
            self.tree.column(j, width=10, anchor=CENTER)
            self.tree.heading(j, text=headings[j])
        for ro in db_cursor:
            self.tree.insert('', i, text="",values=(ro[11], ro[10], ro[3], ro[12], ro[16],ro[8] ,ro[17]))
            i+=1
        self.tree.place(x=295,y=70,height=400,width=900)
        db.close()
        self.vscroll = Scrollbar(root,orient=VERTICAL,command=self.tree.yview)
        self.vscroll.place(x=1195,y=70,height=400)
        self.tree.config(yscrollcommand=self.vscroll.set)
 #=======================================================================================================================       
    def ExitApp(self):
         self.ExitApp = tkinter.messagebox.askquestion ('Exit Portal','Are you sure you want to exit the application. ( Your data is automatically saved )',icon = 'warning')
         if self.ExitApp == 'yes':
            root.destroy()
         else:
            messagebox.showinfo('Return','You will now return to the application screen')
           
    def update_clock(self):
        now = time.strftime("%d %b %Y ,%H:%M:%S")
        self.clck.configure(text=now)
        self.clck.after(1000, self.update_clock)  
        
    def back_win(self):
        self.root.withdraw()
        self.newWindow = Toplevel(self.root)
        self.app = Window1(self.newWindow)   
        
    def allreg_win(self):
        self.root.withdraw()
        self.newWindow = Toplevel(self.root)
        self.app = Windallreg(self.newWindow)      
Exemple #14
0
class ManagerWindow:
    """
    主管理界面入口类,直接无参数创建对象即可。
    """

    # 窗口宽高
    WIN_WIDTH = 800
    WIN_HEIGHT = 600

    def __init__(self):
        # 界面根节点
        self.root = Tk()

        # 主窗口标题
        self.root.title(MANAGER_TITLE)

        # 读取config
        self.config_dict = ConfigOperation.get_dir_from_file()

        # 主窗口分辨率
        self.root.geometry("%sx%s+%s+%s" % (
            self.WIN_WIDTH,
            self.WIN_HEIGHT,
            int((self.root.winfo_screenwidth() - self.WIN_WIDTH) / 2),
            int((self.root.winfo_screenheight() - self.WIN_HEIGHT) / 2)
        ))
        self.root.minsize(self.WIN_WIDTH, self.WIN_HEIGHT)

        # 选项卡
        self.tab_main = Notebook(self.root)
        self.tab_main.pack(expand=True, fill=BOTH)

        # 登录选项卡
        self.frame_login = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_login.pack(side=TOP)
        self.tab_main.add(self.frame_login, text=TAB_NAME_LIST["login"]["text"])

        # 管理选项卡
        self.frame_manage = Frame(self.tab_main, bg=BG_COLOR)
        self.tab_main.add(self.frame_manage, text=TAB_NAME_LIST["manage"]["text"])

        # 好友选项卡
        self.frame_friend = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_friend.pack(side=TOP)
        self.tab_main.add(self.frame_friend, text=TAB_NAME_LIST["friends"]["text"])

        # 群选项卡
        self.frame_group = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_group.pack(side=TOP)
        self.tab_main.add(self.frame_group, text=TAB_NAME_LIST["groups"]["text"])

        # 插件选项卡
        self.frame_plugin = Frame(self.tab_main, bg=BG_COLOR)
        self.frame_plugin.pack(side=TOP)
        self.tab_main.add(self.frame_plugin, text=TAB_NAME_LIST["plugins"]["text"])

        # 初始化登录选项卡
        self.__init_login_tab()

        # 初始化好友选项卡
        self.__init_friend_tab()

        # 初始化群选项卡
        self.__init_group_tab()

        # 初始化管理选项卡
        self.__init_manage_tab()

        # 初始化插件选项卡
        self.__init_plugin_tab()

        # 关闭窗口自动释放Session
        self.root.protocol("WM_DELETE_WINDOW", lambda: self.__on_close_root())

        # 刷新显示
        self.__refresh()

        # 运行相关线程
        fetch_message_thread = FetchMessageThread()
        fetch_message_thread.daemon = True
        fetch_message_thread.start()

        # 运行插件初始化方法
        PluginHandler.call_init()

        # 执行自动连接一次
        self.__auto_connect()

        # 显示
        self.root.mainloop()

    def __init_login_tab(self):
        """
        初始化登录选项卡界面

        :return: 无
        """
        # 左边列表的frame
        frame_login_list = Frame(self.frame_login, bg=BG_COLOR)
        frame_login_list.pack(
            side=LEFT,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 列表,用于保存连接记录
        self.treeview_login_list = Treeview(
            frame_login_list,
            columns=[
                LOGIN_GUIDE["host"],
                LOGIN_GUIDE["port"],
                LOGIN_GUIDE["authkey"],
                LOGIN_GUIDE["qq"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_login_list.pack(
            expand=True,
            fill=BOTH,
            side=LEFT
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["host"],
            width=0
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["host"],
            text=LOGIN_GUIDE["host"]
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["port"],
            width=0
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["port"],
            text=LOGIN_GUIDE["port"]
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["authkey"],
            width=40
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["authkey"],
            text=LOGIN_GUIDE["authkey"]
        )
        self.treeview_login_list.column(
            LOGIN_GUIDE["qq"],
            width=0
        )
        self.treeview_login_list.heading(
            LOGIN_GUIDE["qq"],
            text=LOGIN_GUIDE["qq"]
        )

        # 设定双击事件
        self.treeview_login_list.bind(
            "<Double-Button-1>",
            lambda event: self.__on_double_click_login_list_content()
        )

        # 设定登录列表的滚动条
        scrollbar_login_list = Scrollbar(frame_login_list)
        scrollbar_login_list.pack(fill="y", expand=True)
        self.treeview_login_list.config(yscrollcommand=scrollbar_login_list.set)
        scrollbar_login_list.config(command=self.treeview_login_list.yview)

        # 设置列表右键菜单
        self.treeview_login_list.bind("<Button-3>", self.__show_login_list_pop_up_menu)

        # 登录界面显示的那一坨
        frame_login_menu = Frame(self.frame_login, bg=BG_COLOR)
        frame_login_menu.pack(side=LEFT, padx=5, pady=5)

        # mirai端地址
        Label(frame_login_menu, text=LOGIN_GUIDE["host"], bg=BG_COLOR).grid(row=0, sticky=E, padx=5, pady=5)
        self.entry_host = Entry(frame_login_menu)
        self.entry_host.grid(row=0, column=1, sticky=W, padx=5, pady=5)

        # mirai端端口号
        Label(frame_login_menu, text=LOGIN_GUIDE["port"], bg=BG_COLOR).grid(row=1, sticky=E, padx=5, pady=5)
        self.entry_port = Entry(frame_login_menu)
        self.entry_port.grid(row=1, column=1, sticky=W, padx=5, pady=5)

        # mirai端http授权码
        Label(frame_login_menu, text=LOGIN_GUIDE["authkey"], bg=BG_COLOR).grid(
            row=2,
            sticky=E,
            padx=5,
            pady=5
        )
        self.entry_authkey = Entry(frame_login_menu, show=PWD_CHAR_CIRCLE)
        self.entry_authkey.grid(row=2, column=1, sticky=W, padx=5, pady=5)

        # 用于激活sessioKey的qq号码
        Label(frame_login_menu, text=LOGIN_GUIDE["qq"], bg=BG_COLOR).grid(
            row=3,
            sticky=E,
            padx=5,
            pady=5
        )
        self.entry_qq = Entry(frame_login_menu)
        self.entry_qq.grid(row=3, column=1, sticky=W, padx=5, pady=5)

        # 自动连接复选框
        self.auto_connect_var = BooleanVar()
        self.checkbutton_auto_connect = Checkbutton(
            frame_login_menu,
            text=AUTO_CONNECT_GUIDE,
            onvalue=True,
            offvalue=False,
            variable=self.auto_connect_var,
            bg=BG_COLOR
        )
        self.checkbutton_auto_connect.grid(row=4, column=0, padx=5, pady=5, columnspan=2)

        # 连接按钮
        self.btn_connect = Button(
            frame_login_menu,
            text=BTN_TEXT_CONN["connect"],
            width=15,
            command=lambda: self.__on_click_connect_event(),
        )
        self.btn_connect.grid(row=5, columnspan=2, padx=5, pady=5)

        # 添加到登录列表按钮
        self.btn_save_login = Button(
            frame_login_menu,
            width=15,
            text=BTN_TEXT_ADD_LOGIN,
            command=lambda: self.__on_click_add_to_login_list()
        )
        self.btn_save_login.grid(row=6, columnspan=2, padx=5, pady=5)

        # 状态栏
        self.label_login_status_bar = Label(
            self.root,
            text=LOGIN_STATUS_BAR_TEXT["notConnect"],
            fg=STATUS_BAR_COLOR["normal"]
        )
        self.label_login_status_bar.pack(side=LEFT)

        # 下面开始从config中将内容填充进文本框中
        self.entry_host.delete(0, END)
        self.entry_host.insert(END, self.config_dict["lastConnection"]["host"])
        self.entry_port.delete(0, END)
        self.entry_port.insert(END, self.config_dict["lastConnection"]["port"])
        self.entry_authkey.delete(0, END)
        self.entry_authkey.insert(END, self.config_dict["lastConnection"]["authkey"])
        self.entry_qq.delete(0, END)
        self.entry_qq.insert(END, self.config_dict["lastConnection"]["qq"])

        # 自动连接复选框内容
        self.auto_connect_var.set(self.config_dict["autoConnect"])

    def __init_friend_tab(self):
        """
        初始化好友选项卡内容

        :return: 无
        """

        # 创建好友列表框架
        frame_friend_list = Frame(self.frame_friend, bg=BG_COLOR)
        frame_friend_list.pack(
            side=LEFT,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 创建消息测试发送框架
        frame_friend_send = Frame(self.frame_friend, bg=BG_COLOR)
        frame_friend_send.pack(
            side=LEFT,
            padx=5,
            pady=5
        )

        # 设置列表
        self.treeview_friend_list = Treeview(
            frame_friend_list,
            columns=[
                FRIEND_GUIDE["qq"],
                FRIEND_GUIDE["nickname"],
                FRIEND_GUIDE["remark"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_friend_list.pack(
            expand=True,
            fill=BOTH,
            side=LEFT
        )
        self.treeview_friend_list.column(
            FRIEND_GUIDE["qq"],
            width=0
        )
        self.treeview_friend_list.heading(
            FRIEND_GUIDE["qq"],
            text=FRIEND_GUIDE["qq"]
        )
        self.treeview_friend_list.column(
            FRIEND_GUIDE["nickname"],
            width=0
        )
        self.treeview_friend_list.heading(
            FRIEND_GUIDE["nickname"],
            text=FRIEND_GUIDE["nickname"]
        )
        self.treeview_friend_list.column(
            FRIEND_GUIDE["remark"],
            width=0
        )
        self.treeview_friend_list.heading(
            FRIEND_GUIDE["remark"],
            text=FRIEND_GUIDE["remark"]
        )

        # 设定好友列表的滚动条
        scrollbar_friend_list = Scrollbar(frame_friend_list)
        scrollbar_friend_list.pack(fill="y", expand=True)
        self.treeview_friend_list.config(yscrollcommand=scrollbar_friend_list.set)
        scrollbar_friend_list.config(command=self.treeview_friend_list.yview)

        # 刷新列表按钮
        Button(
            frame_friend_send,
            text=BTN_FRIEND_REFRESH,
            command=lambda: self.__on_click_refresh_friend_list_event()
        ).grid(row=0, padx=5, pady=5)

        # 发送纯文本窗口标题
        Label(frame_friend_send, text=SEND_TITLE, bg=BG_COLOR).grid(row=1, padx=5, pady=5)

        # 发送纯文本窗口
        self.text_friend_send = Text(frame_friend_send, width=30, height=5)
        self.text_friend_send.grid(row=2, padx=5, pady=5)

        # 发送按钮
        Button(
            frame_friend_send,
            text=BTN_SEND,
            command=lambda: self.__on_click_send_friend_message()
        ).grid(row=3, padx=5, pady=5)

    def __init_group_tab(self):
        """
        初始化群选项卡内容

        :return: 无
        """

        # 创建好友列表框架
        frame_group_list = Frame(self.frame_group, bg=BG_COLOR)
        frame_group_list.pack(
            side=LEFT,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 创建消息测试发送框架
        frame_group_send = Frame(self.frame_group, bg=BG_COLOR)
        frame_group_send.pack(
            side=LEFT,
            padx=5,
            pady=5
        )

        # 设置列表
        self.treeview_group_list = Treeview(
            frame_group_list,
            columns=[
                GROUP_GUIDE["group"],
                GROUP_GUIDE["name"],
                GROUP_GUIDE["permission"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_group_list.pack(
            expand=True,
            fill=BOTH,
            side=LEFT
        )
        self.treeview_group_list.column(
            GROUP_GUIDE["group"],
            width=0
        )
        self.treeview_group_list.heading(
            GROUP_GUIDE["group"],
            text=GROUP_GUIDE["group"]
        )
        self.treeview_group_list.column(
            GROUP_GUIDE["name"],
            width=0
        )
        self.treeview_group_list.heading(
            GROUP_GUIDE["name"],
            text=GROUP_GUIDE["name"]
        )
        self.treeview_group_list.column(
            GROUP_GUIDE["permission"],
            width=0
        )
        self.treeview_group_list.heading(
            GROUP_GUIDE["permission"],
            text=GROUP_GUIDE["permission"]
        )

        # 设定群列表的滚动条
        scrollbar_group_list = Scrollbar(frame_group_list)
        scrollbar_group_list.pack(fill="y", expand=True)
        self.treeview_group_list.config(yscrollcommand=scrollbar_group_list.set)
        scrollbar_group_list.config(command=self.treeview_group_list.yview)

        # 刷新列表按钮
        Button(
            frame_group_send,
            text=BTN_GROUP_REFRESH,
            command=lambda: self.__on_click_refresh_group_list_event()
        ).grid(row=0, padx=5, pady=5)

        # 发送纯文本窗口标题
        Label(frame_group_send, text=SEND_TITLE, bg=BG_COLOR).grid(row=1, padx=5, pady=5)

        # 发送纯文本窗口
        self.text_group_send = Text(frame_group_send, width=30, height=5)
        self.text_group_send.grid(row=2, padx=5, pady=5)

        # 发送按钮
        Button(
            frame_group_send,
            text=BTN_SEND,
            command=lambda: self.__on_click_send_group_message()
        ).grid(row=3, padx=5, pady=5)

    def __init_manage_tab(self):
        """
        初始化管理选项卡

        :return: 无
        """

        f_manage = Frame(self.frame_manage, bg=BG_COLOR)
        f_manage.pack(padx=5, pady=5, expand=True)

        # 指定头指示
        Label(f_manage, text=MANAGE_GUIDE["commandHead"], bg=BG_COLOR).grid(
            row=0,
            column=0,
            padx=5,
            pady=5,
            sticky=E
        )

        # 指令头文本框
        self.entry_command_head = Entry(f_manage)
        self.entry_command_head.grid(row=0, column=1, padx=5, pady=5, sticky=EW)

        # 调试复选框
        self.debug_var = BooleanVar()
        checkbutton_debug = Checkbutton(
            f_manage,
            text=MANAGE_GUIDE["debug"],
            onvalue=True,
            offvalue=False,
            variable=self.debug_var,
            bg=BG_COLOR
        )
        checkbutton_debug.grid(row=1, column=0, columnspan=3, padx=5, pady=5)

        # 启用机器人
        self.enable_var = BooleanVar()
        checkbutton_enable = Checkbutton(
            f_manage,
            text=MANAGE_GUIDE["enable"],
            onvalue=True,
            offvalue=False,
            variable=self.enable_var,
            bg=BG_COLOR
        )
        checkbutton_enable.grid(row=2, column=0, columnspan=3, padx=5, pady=5)

        # 配置保存
        Button(
            f_manage,
            text=MANAGE_GUIDE["saveConfig"],
            command=self.__on_click_save_config
        ).grid(
            row=3,
            column=1,
            padx=5,
            pady=5,
            sticky=EW
        )

        # bot管理qq列表
        self.treeview_op_list = Treeview(
            f_manage,
            columns=[
                MANAGE_GUIDE["botOpQQ"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_op_list.column(MANAGE_GUIDE["botOpQQ"], width=200)
        self.treeview_op_list.heading(MANAGE_GUIDE["botOpQQ"], text=MANAGE_GUIDE["botOpQQ"])
        self.treeview_op_list.grid(
            row=4,
            column=0,
            columnspan=3,
            rowspan=10,
            sticky=EW
        )

        # 列表右键
        self.treeview_op_list.bind("<Button-3>", self.__show_op_list_pop_up_menu)

        # 添加管理标签
        Label(f_manage, text=MANAGE_GUIDE["addOpQQ"], bg=BG_COLOR).grid(row=14, column=0, padx=5, pady=5)

        # 添加管理文本框
        self.entry_add_op = Entry(f_manage)
        self.entry_add_op.grid(row=14, column=1, padx=5, pady=5)

        # 添加添加按钮
        Button(
            f_manage,
            text=MANAGE_GUIDE["btnAddOpQQ"],
            command=lambda: self.__on_click_add_op()
        ).grid(row=14, column=2, padx=5, pady=5, sticky=EW)

    def __init_plugin_tab(self):
        """
        初始化插件选项卡

        :return: 无
        """

        # 指示标签
        Label(self.frame_plugin, text=PLUGIN_LABEL_TEXT, bg=BG_COLOR).pack(side=TOP)

        # 插件列表frame
        frame_plugin_list = Frame(self.frame_plugin, bg=BG_COLOR)
        frame_plugin_list.pack(
            side=TOP,
            expand=True,
            fill=BOTH,
            padx=5,
            pady=5
        )

        # 插件列表
        self.treeview_plugin_list = Treeview(
            frame_plugin_list,
            columns=[
                PLUGIN_GUIDE["pluginName"]
            ],
            show="headings",
            selectmode=BROWSE
        )
        self.treeview_plugin_list.pack(fill=BOTH, expand=True, side=LEFT)
        self.treeview_plugin_list.column(PLUGIN_GUIDE["pluginName"])
        self.treeview_plugin_list.heading(PLUGIN_GUIDE["pluginName"], text=PLUGIN_GUIDE["pluginName"])

        # 设定插件列表滚动条
        scrollbar_plugin_list = Scrollbar(frame_plugin_list)
        scrollbar_plugin_list.pack(fill="y", expand=True)
        self.treeview_plugin_list.config(yscrollcommand=scrollbar_plugin_list.set)
        scrollbar_plugin_list.config(command=self.treeview_plugin_list.yview)

    def __on_click_connect_event(self):
        """
        点击连接按钮事件

        :return: 无
        """

        if not GlobalValues.is_connected:
            # 如果是要连接

            # 存到全局使用变量
            GlobalValues.conn_host = self.entry_host.get()
            GlobalValues.conn_port = self.entry_port.get()
            GlobalValues.conn_authkey = self.entry_authkey.get()
            try:
                # 转换为整型后保存
                GlobalValues.conn_qq = int(self.entry_qq.get())
            except ValueError:
                self.label_login_status_bar.config(text=LOGIN_STATUS_BAR_TEXT["wrongQQ"], fg=STATUS_BAR_COLOR["failed"])
                return

            # 修改界面上的一些内容为不可修改
            self.__set_login_tools_active(False)

            # 修改按钮内容
            self.btn_connect.config(text=BTN_TEXT_CONN["disconnect"])

            # 修改状态栏内容
            self.label_login_status_bar.config(text=LOGIN_STATUS_BAR_TEXT["connecting"], fg=STATUS_BAR_COLOR["normal"])

            # 调用连接
            try:
                Conn.new_session_key()
            except (
                requests.exceptions.InvalidURL,
                requests.exceptions.ConnectionError,
            ):
                # 连接错误

                # 错误信息显示到状态栏
                self.label_login_status_bar.config(
                    text=LOGIN_STATUS_BAR_TEXT["connectFailed"],
                    fg=STATUS_BAR_COLOR["failed"]
                )

                # 修改文本框为可修改
                self.__set_login_tools_active(True)
                self.btn_connect.config(text=BTN_TEXT_CONN["connect"])
                return
            except WrongAuthkeyException:
                # 授权码错误

                # 显示到状态栏
                self.label_login_status_bar.config(
                    text=LOGIN_STATUS_BAR_TEXT["wrongAuthkey"],
                    fg=STATUS_BAR_COLOR["failed"]
                )

                # 修改文本框为可修改
                self.__set_login_tools_active(True)
                self.btn_connect.config(text=BTN_TEXT_CONN["connect"])
                return

            except BotNotExistException:
                # bot不存在错误
                self.label_login_status_bar.config(
                    text=LOGIN_STATUS_BAR_TEXT["qqNotExist"],
                    fg=STATUS_BAR_COLOR["failed"]
                )

                # 修改文本框为可修改
                self.__set_login_tools_active(True)
                self.btn_connect.config(text=BTN_TEXT_CONN["connect"])
                return

            self.label_login_status_bar.config(
                text=LOGIN_STATUS_BAR_TEXT["connected"],
                fg=STATUS_BAR_COLOR["passed"]
            )

            # 修改连接状态值
            GlobalValues.is_connected = True

            # 修改上次连接键值对
            ConfigOperation.modify_dict("lastConnection", {
                "host": GlobalValues.conn_host,
                "port": GlobalValues.conn_port,
                "authkey": GlobalValues.conn_authkey,
                "qq": GlobalValues.conn_qq
            })

            # 修改文件中自动连接开关
            ConfigOperation.modify_dict("autoConnect", self.auto_connect_var.get())

        else:
            # 如果要断开连接

            # 修改文本框为可修改
            self.__set_login_tools_active(True)

            # 修改按钮名称
            self.btn_connect.config(text=BTN_TEXT_CONN["connect"])

            # 修改属性值
            self.label_login_status_bar.config(
                text=LOGIN_STATUS_BAR_TEXT["disconnectSuccess"],
                fg=STATUS_BAR_COLOR["normal"]
            )

            # 释放session
            Conn.release_session_key()

            # 修改连接状态值
            GlobalValues.is_connected = False

    def __set_login_tools_active(self, active: bool):
        """
        修改界面上的一些内容为不可修改

        :param active: bool,如果为False则禁用掉文本框,否则启用
        :return: 无
        """
        if active:
            self.entry_host.config(state=ACTIVE)
            self.entry_port.config(state=ACTIVE)
            self.entry_authkey.config(state=ACTIVE)
            self.entry_qq.config(state=ACTIVE)
            self.checkbutton_auto_connect.config(state=ACTIVE)
        else:
            self.entry_host.config(state=DISABLED)
            self.entry_port.config(state=DISABLED)
            self.entry_authkey.config(state=DISABLED)
            self.entry_qq.config(state=DISABLED)
            self.checkbutton_auto_connect.config(state=DISABLED)

    def __on_close_root(self):
        """
        关闭窗口的事件
        :return: 无
        """

        # 如果正在连接则释放连接
        if GlobalValues.is_connected:
            Conn.release_session_key()

        # 杀掉root
        self.root.destroy()

    def __refresh(self):
        """
        用于刷新界面,在必要时调用

        :return: 无
        """

        def refresh_login_list():
            """
            刷新登录列表

            :return: 无
            """

            # 删除目前表中的所有内容
            self.treeview_login_list.delete(*self.treeview_login_list.get_children())

            # 把登录列表内容添加到显示中
            for one_record in LoginListOperation.get_list_from_file():
                self.treeview_login_list.insert("", index=END, values=(
                    one_record["host"],
                    one_record["port"],
                    one_record["authkey"],
                    one_record["qq"]
                ))

        def refresh_op_list():
            """
            刷新bot管理员qq列表

            :return: 无
            """

            # 删除目前表中的所有内容
            self.treeview_op_list.delete(*self.treeview_op_list.get_children())

            # 把内容添加到显示中
            for one_record in OpListOperation.get_list():
                self.treeview_op_list.insert("", index=END, values=(
                    one_record
                ))

        def refresh_config():
            """
            刷新配置

            :return: 无
            """
            # 重新获取config
            self.config_dict = ConfigOperation.get_dir_from_file()

            # 将文件中的内容显示到界面中
            self.entry_command_head.delete(0, END)
            self.entry_command_head.insert(END, self.config_dict["commandHead"])

            # 设置复选框默认勾选
            self.debug_var.set(self.config_dict["debug"])
            self.enable_var.set(self.config_dict["enable"])

            # 将内容设置到全局变量
            GlobalValues.command_head = self.config_dict["commandHead"]
            GlobalValues.debug_var = self.debug_var
            GlobalValues.enable_var = self.enable_var

        def refresh_plugin_list():
            # 获取插件名称
            plugin_names = PluginHandler.get_plugin_name_list()

            # 显示
            self.treeview_plugin_list.delete(*self.treeview_plugin_list.get_children())
            for name in plugin_names:
                self.treeview_plugin_list.insert("", index=END, values=(
                    name
                ))

        # 调用刷新登录列表
        refresh_login_list()

        # 调用刷新op列表
        refresh_op_list()

        # 刷新config显示
        refresh_config()

        # 刷新插件列表显示
        refresh_plugin_list()

    def __on_click_add_to_login_list(self):
        """
        将填写内容添加到列表中
        :return: 无
        """

        # 非空检测
        if [
            self.entry_host.get(),
            self.entry_port.get(),
            self.entry_authkey.get(),
            self.entry_qq.get()
        ] == [""] * 4:
            return

        # 调用添加登录项方法
        LoginListOperation.add_to_list(
            self.entry_host.get(),
            self.entry_port.get(),
            self.entry_authkey.get(),
            self.entry_qq.get()
        )

        # 刷新显示
        self.__refresh()

    def __on_double_click_login_list_content(self):
        """
        双击登录列表项目时,自动填充到右侧

        :return: 无
        """

        # 获取item的值
        item_list = self.treeview_login_list.item(self.treeview_login_list.focus(), "values")

        # 获取需要的项目并设置
        self.entry_host.delete(0, END)
        self.entry_host.insert(END, item_list[0])
        self.entry_port.delete(0, END)
        self.entry_port.insert(END, item_list[1])
        self.entry_authkey.delete(0, END)
        self.entry_authkey.insert(END, item_list[2])
        self.entry_qq.delete(0, END)
        self.entry_qq.insert(END, item_list[3])

    def __show_login_list_pop_up_menu(self, event):
        """
        显示右键菜单

        :param event: 事件
        :return: 无
        """
        def on_delete_event(item_id):
            """
            删除选项的事件

            :return: 无
            """

            # 删除该项
            LoginListOperation.remove_from_list(*self.treeview_login_list.item(item_id, "values"))
            self.treeview_login_list.delete(item_id)
            self.__refresh()

        # 获取选择对象
        iid = self.treeview_login_list.identify_row(event.y)

        # 如果有选择,则弹出右键菜单
        if iid:
            self.treeview_login_list.selection_set(iid)
            menu_pop_up = Menu(self.treeview_login_list, tearoff=False)
            menu_pop_up.add_command(
                label=POP_UP_MENU_DELETE_STR,
                command=lambda: on_delete_event(iid)
            )
            menu_pop_up.post(event.x_root, event.y_root)

    def __on_click_refresh_friend_list_event(self):
        """
        点击刷新好友列表事件

        :return: 无
        """
        try:
            # 如果未连接,则可能会抛出异常,此处直接弹出错误消息框
            friend_list = Conn.get_friend_list()
        except:
            messagebox.showerror(message=REFRESH_ERROR_MSG)
            return

        # 删除列表内容
        self.treeview_friend_list.delete(*self.treeview_friend_list.get_children())

        # 解析friend_list
        for friend_block in friend_list:
            self.treeview_friend_list.insert("", index=END, values=(
                friend_block["id"],
                friend_block["nickname"],
                friend_block["remark"]
            ))

    def __on_click_refresh_group_list_event(self):
        """
        点击刷新群列表事件

        :return: 无
        """
        try:
            # 如果未连接,则可能会抛出异常,此处直接弹出错误消息框
            group_list = Conn.get_group_list()
        except:
            messagebox.showerror(message=REFRESH_ERROR_MSG)
            return

        # 删除列表内容
        self.treeview_group_list.delete(*self.treeview_group_list.get_children())

        # 解析group_list
        for group_block in group_list:
            self.treeview_group_list.insert("", index=END, values=(
                group_block["id"],
                group_block["name"],
                group_block["permission"]
            ))

    def __on_click_send_friend_message(self):
        """
        点击发送消息给好友按钮

        :return: 无
        """

        # 获取到选中好友的值列表
        value_list = self.treeview_friend_list.item(self.treeview_friend_list.focus(), "values")

        try:
            # 获取qq并发送消息
            qq = value_list[0]
            message_chain = MessageChain()
            text = self.text_friend_send.get(1.0, END)
            if text == "\n":
                return
            message_chain.add_plain_text(text)
            Conn.send_friend_message(qq, message_chain)
            self.text_friend_send.delete(1.0, END)
        except:
            messagebox.showerror(message=SEND_ERROR_MSG)
            return

    def __on_click_send_group_message(self):
        """
        点击发送消息给群按钮

        :return: 无
        """

        # 获取到选中群的值列表
        value_list = self.treeview_group_list.item(self.treeview_group_list.focus(), "values")

        try:
            # 获取qq并发送消息
            qq = value_list[0]
            message_chain = MessageChain()
            text = self.text_group_send.get(1.0, END)
            if text == "\n":
                return
            message_chain.add_plain_text(text)
            Conn.send_group_message(qq, message_chain)
            self.text_group_send.delete(1.0, END)
        except:
            messagebox.showerror(message=SEND_ERROR_MSG)
            return



    def __on_click_add_op(self):
        """
        点击添加op按钮事件

        :return: 无
        """

        content = self.entry_add_op.get()

        # 如果添加op的文本框中没有东西,则不添加
        if content == "":
            return

        # 如果转换数字出错则不添加
        try:
            op_qq = int(content)
        except ValueError:
            return

        # 添加到op列表中
        OpListOperation.add_to_list(op_qq)

        # 刷新显示
        self.__refresh()

    def __show_op_list_pop_up_menu(self, event):
        """
        op列表右键菜单

        :return: 无
        """

        def on_delete_event():
            """
            删除选项的事件

            :return: 无
            """

            # 删除该项
            # 注意此处的强转,由于能够保证显示出来的内容一定只含有数字,故可以直接转换
            OpListOperation.remove_from_list(int(self.treeview_op_list.item(op_qq, "values")[0]))
            self.treeview_op_list.delete(op_qq)
            self.__refresh()

        # 获取选择对象
        op_qq = self.treeview_op_list.identify_row(event.y)

        # 如果有选择,则弹出右键菜单
        if op_qq:
            menu_pop_up = Menu(self.treeview_op_list, tearoff=False)
            self.treeview_op_list.selection_set(op_qq)
            menu_pop_up.add_command(
                label=POP_UP_MENU_DELETE_STR,
                command=lambda: on_delete_event()
            )
            menu_pop_up.post(event.x_root, event.y_root)

    def __on_click_save_config(self):
        """
        点击保存配置事件

        :return: 无
        """

        content = self.entry_command_head.get()

        # 如果为空,则不存入,但是刷新
        # 这样是为了保证点击后会显示原来的设置
        if content == "":
            self.__refresh()
            return

        ConfigOperation.modify_dict("commandHead", content)
        ConfigOperation.modify_dict("debug", self.debug_var.get())
        ConfigOperation.modify_dict("enable", self.enable_var.get())

        # 刷新
        self.__refresh()

        # 弹出对话框
        messagebox.showinfo(message=MANAGE_GUIDE["successSaveCommandHeadMsg"])

    def __auto_connect(self):
        if self.config_dict["autoConnect"]:
            self.__on_click_connect_event()
Exemple #15
0
    def listchans(self,
                  index=None,
                  tagsearch="",
                  archived=0,
                  ob=Channel.displayname,
                  so=asc):
        self.center = Frame(root,
                            bg=config.bgcolor,
                            width=50,
                            height=40,
                            padx=3,
                            pady=3)

        # layout all of the main containers
        root.grid_rowconfigure(1, weight=1)
        root.grid_columnconfigure(0, weight=1)
        self.center.grid(row=1, sticky="nsew")

        channels = database.get_channels(archived, ob, so)
        if so == desc:
            so = asc
        else:
            so = desc

        tree = Treeview(self.center)

        sstring = Entry(self.center, width=config.textBoxWidth)
        sstring.bind(
            "<KeyRelease-Return>",
            lambda e: self.listchans(None, sstring.get(), archived, ob, so))
        sstring.grid(column=0, row=0)
        if len(tagsearch) >= 1:
            sstring.focus()
            sstring.insert(0, tagsearch)
        searchbutton = Button(self.center,
                              text="Search",
                              command=lambda: self.listchans(
                                  None, sstring.get(), archived, ob, so))
        searchbutton.grid(column=1, row=0)

        clearbutton = Button(self.center, text="Clear Search")
        clearbutton.configure(command=lambda: self.listchans(archived))
        clearbutton.grid(column=3, row=0)

        tree["columns"] = ("one", "two")

        tree.column("#0", width=210, minwidth=10, stretch=YES)
        tree.column("one", width=350, minwidth=250, stretch=YES)
        tree.column("two", width=210, minwidth=10, stretch=YES)

        tree.heading("#0",
                     text="Last Check",
                     anchor=W,
                     command=lambda: self.listchans(None, sstring.get(
                     ), archived, Channel.lastcheck, so))

        tree.heading("one",
                     text="Channel Name",
                     anchor=E,
                     command=lambda: self.listchans(None, sstring.get(
                     ), archived, Channel.displayname, so))
        tree.heading("two",
                     text="Last Published",
                     command=lambda: self.listchans(None, sstring.get(
                     ), archived, Channel.lastpub, so))
        i = 0
        tree.tag_configure('oddrow', background='#88DD88')
        tree.tag_configure('evenrow', background='#FFFFFF')
        tree.tag_configure('archivedodd',
                           background="#88DD88",
                           foreground="#aaaaaa")
        tree.tag_configure('archivedeven',
                           background='#FFFFFF',
                           foreground="#cccccc")

        for item in channels:
            foldername = "folder" + str(i)

            if i % 2 == 0:
                color = "evenrow"
            else:
                color = "oddrow"

            if item.archive == True:
                if i % 2 == 0:
                    color = "archivedeven"
                else:
                    color = "archivedodd"

            if tagsearch.lower() in str(
                    item.displayname).lower() or tagsearch.lower() in str(
                        item.dldir).lower() or tagsearch.lower() in str(
                            item.yt_channelid).lower():
                if item.lastpub == None:
                    lastpub = "N/A"
                else:
                    lastpub = time.ctime(item.lastpub)

                foldername = tree.insert("",
                                         "end",
                                         text=time.ctime(item.lastcheck),
                                         values=(item.displayname, lastpub),
                                         tags=(color, item.displayname,
                                               item.dldir, item.yt_channelid))

                tree.insert(foldername,
                            "end",
                            text="Directory",
                            values=(item.dldir, ),
                            tags=(color))

                tree.insert(foldername,
                            "end",
                            text="Last Published",
                            values=(lastpub, ),
                            tags=(color))

                i = i + 1

        vertscroll = Scrollbar(self.center)
        vertscroll.config(command=tree.yview)
        tree.config(yscrollcommand=vertscroll.set, height=20)
        vertscroll.grid(column=4, row=1, sticky='NSE')
        tree.bind("<Double-1>", self.item_selected)

        tree.grid(row=1, columnspan=4, sticky="NSEW")
        tree.focus(index)
        tree.selection_set(index)
        tree.see(index)
Exemple #16
0
class CsvFrame:
    """ Display csv data in a tkinter TreeView """

    def __init__(self, parent, manager):
        """ CsvFrame constructor """
        top = self.top = tkinter.Toplevel(parent)
        self.__parent = parent
        self.__manager = manager

        top_frame = tkinter.Frame(top, borderwidth=2, relief=tkinter.GROOVE)
        top_frame.pack(side=tkinter.TOP, fill=tkinter.X, padx=5, pady=5)

        label_data = Label(top_frame, text="Data: ")
        label_data.grid(row=1, column=1, padx=5, pady=5)
        data_select_combo3 = tkinter.StringVar()
        self.combo_data = Combobox(top_frame, textvariable=data_select_combo3, values=manager.get_field_names(),
                                   state='readonly',
                                   postcommand=lambda: self.combo_data.configure(values=manager.get_field_names()))
        self.combo_data.grid(row=1, column=2, padx=5, pady=5)

        edit_button = Button(top_frame, text="Edit header", command=self.edit_header, width=20)
        edit_button.grid(row=1, column=3, columnspan=1, rowspan=1, padx=5, pady=5)

        # TODO change values for combobox
        transform_select_combo4 = tkinter.StringVar()
        self.combo_transform = Combobox(top_frame, textvariable=transform_select_combo4, values=["rad_to_deg",
                                                                                                       "deg_to_rad"],
                                        state='readonly')
        self.combo_transform.grid(row=1, column=4, padx=5, pady=5)

        transform_button = Button(top_frame, text="Transform data", command=self.transform_data, width=20)
        transform_button.grid(row=1, column=5, columnspan=1, rowspan=1, padx=5, pady=5)

        table_frame = Frame(top)
        table_frame.pack(side=tkinter.BOTTOM, expand=True, fill=tkinter.BOTH)

        scrollbar_x = Scrollbar(table_frame, orient=tkinter.HORIZONTAL)
        scrollbar_y = Scrollbar(table_frame, orient=tkinter.VERTICAL)

        self.tree = Treeview(table_frame, columns=manager.get_field_names(), show="headings", selectmode="extended",
                             yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)

        scrollbar_y.config(command=self.tree.yview)
        scrollbar_y.pack(side=tkinter.RIGHT, fill=tkinter.Y)
        scrollbar_x.config(command=self.tree.xview)
        scrollbar_x.pack(side=tkinter.BOTTOM, fill=tkinter.X)

        self.fill_data()

        self.tree.pack(expand=True, fill=tkinter.BOTH)
        self.top.protocol("WM_DELETE_WINDOW", self.quit)

    def edit_header(self):
        """ Edit the header a data column """
        if self.combo_data.get() != "":
            answer = simpledialog.askstring("Input", "What is the new header?", parent=self.top)
            if answer is not None:
                self.__manager.edit_header(answer, self.combo_data.get())
                self.fill_data()
                self.combo_data.set('')
            else:
                logger.log(logging.INFO, "[CsvFrame] No new header entered")
        else:
            logger.log(logging.ERROR, "[CsvFrame] No data field selected")

    def clear_data(self):
        """ Clear data in Treeview """
        logger.log(logging.INFO, "[CsvFrame] Clear data in TreeView")
        for i in self.tree.get_children():
            self.tree.delete(i)

    def fill_data(self):
        """ Fill data in Treeview """
        logger.log(logging.INFO, "[CsvFrame] Fill data in TreeView")

        self.clear_data()
        self.tree.config(columns=self.__manager.get_field_names())

        for field_name in self.__manager.get_field_names():
            self.tree.heading(field_name, text=field_name, anchor=tkinter.W)
            self.tree.column(field_name, stretch=tkinter.YES)

        for entry in self.__manager.get_data_tuple():
            self.tree.insert("", 'end', values=entry)

    def transform_data(self):
        """ Transform data and add in Treeview """
        # TODO to be completed
        data_field_name = self.combo_data.get()
        if data_field_name != "":
            if self.combo_transform.get() != "":
                data = self.__manager.get_data_from_field_name(data_field_name)
                transformed_data = transform_data(self.combo_transform.get(), self.combo_data.get(), data)
                if transformed_data[0] != "":
                    self.__manager.add_data(transformed_data[0], transformed_data[1], transformed_data[2])
                    self.fill_data()
                else:
                    logger.log(logging.ERROR, "[CsvFrame] Data has not been transformed")
            else:
                logger.log(logging.ERROR, "[CsvFrame] No transform operation selected")
        else:
            logger.log(logging.ERROR, "[CsvFrame] No data field selected")

    def quit(self):
        """ Destroy the frame """
        self.__parent.reset_csvframe()
        self.top.destroy()
Exemple #17
0
class LDAPConsole(Frame):
    def __init__(self):
        super().__init__()
        self.initConsole()
        self.addMenuBar()
        self.createSections()

    def initConsole(self):
        self.master.title("LDAP Management Console")
        self.style = Style()
        self.style.theme_use("alt")
        ## Frame principal.
        self.pack(fill=BOTH, expand=1)

    def addMenuBar(self):
        ## Creacion de barra de menus.
        menubar = Menu(self.master)
        self.master.config(menu=menubar)
        ## Seccion File del menu.
        fileMenu = Menu(menubar, tearoff=0)
        fileMenu.add_command(label="Connect", command=self.OpenConnection)
        fileMenu.add_command(label="Disconnect", command=self.CloseConnection)
        fileMenu.add_separator()
        fileMenu.add_command(label="Exit", command=self.ExitOption)
        menubar.add_cascade(label="File", menu=fileMenu)
        ## Seccion Advanced del menu.
        AdvancedMenu = Menu(menubar, tearoff=0)
        AdvancedMenu.add_command(label="Display Options")
        AdvancedMenu.add_command(label="Verify")
        AdvancedMenu.add_command(label="Configure")
        menubar.add_cascade(label="Advanced", menu=AdvancedMenu)
        ## Seccion Help del menu.
        HelpMenu = Menu(menubar, tearoff=0)
        HelpMenu.add_command(label="Show Help")
        HelpMenu.add_command(label="About LDAP GUI")
        menubar.add_cascade(label="Help", menu=HelpMenu)

    def createSections(self):
        ## Definicion de frames secundarios anidados en el principal.
        ## Nuevo Frame para contener la representacion del arbol de
        ## directorio incluyendo las barras de desplazamiento.
        self.treeNavFrame = Frame(self)
        self.treeNavFrame.config(relief=RAISED, borderwidth=2)
        self.treeNavView = Treeview(self.treeNavFrame,
                                    show="tree",
                                    selectmode="browse")
        ## Definicion de barras de desplazamiento.
        ## La barra de desplazamiento tiene como padre el Frame pero controla
        ## el widget treeview.
        ### Barra de desplazamiento horizontal.
        self.HorScrollBar = Scrollbar(self.treeNavFrame,
                                      activerelief=RAISED,
                                      orient=HORIZONTAL)
        self.HorScrollBar.config(command=self.treeNavView.xview)
        self.HorScrollBar.pack(fill=X, side=BOTTOM)
        ### Barra de desplazamiento vertical.
        self.VerScrollBar = Scrollbar(self.treeNavFrame,
                                      activerelief=RAISED,
                                      orient=VERTICAL)
        self.VerScrollBar.config(command=self.treeNavView.yview)
        self.VerScrollBar.pack(fill=Y, side=RIGHT)

        self.treeNavFrame.pack(fill=BOTH, side=LEFT)
        self.treeNavView.pack(fill=BOTH, side=LEFT)

        self.treeNavView.config(xscrollcommand=self.HorScrollBar.set,
                                yscrollcommand=self.VerScrollBar.set)
        ## Nuevo frame para contener la informacion de objetos seleccionados.
        self.infoFrame = Frame(self)
        self.infoFrame.config(relief=RAISED, borderwidth=2)
        self.infoFrameCanvas = Canvas(self.infoFrame,
                                      bg="white",
                                      width=500,
                                      height=400)
        self.infoFrameCanvas.pack(fill=X, anchor=NE)
        self.infoFrame.pack(fill=X, anchor=NE)

    def updateInfoSection(self, dntoSearch, infoToDisplay):
        try:
            self.infoFrameCanvas.delete("all")
            self.infoFrameCanvas.create_text(20,
                                             20,
                                             font=("Liberation Serif Bold", 30,
                                                   "bold"),
                                             anchor=W,
                                             text="{}".format(dntoSearch[0]))
            row = 50
            self.infoFrameCanvas.create_text(20,
                                             row,
                                             font=("Liberation Serif Bold",
                                                   20),
                                             anchor=W,
                                             text="objectClass: ")
            for objclass in infoToDisplay[0]["attributes"]["objectClass"]:
                self.infoFrameCanvas.create_text(160,
                                                 row,
                                                 font=("Liberation Serif Bold",
                                                       10),
                                                 anchor=W,
                                                 text="{}".format(objclass))
                row += 20
                print(objclass)
        except:
            print("Error en updateInfoSection")

    def contextOperations(self, cadena, elLDAPObject, operationType):
        try:
            if (operationType == "REFRESH"):
                print("Refresh sobre {}.".format(cadena))
            if (operationType == "ADD"):
                print("Nueva entrada sobre {}.".format(cadena))
            if (operationType == "DELETE"):
                print("Borrar entrada sobre {}.".format(cadena))
            if (operationType == "MOVE"):
                print("Mover entrada sobre {}.".format(cadena))
        except:
            print("Error en contextOperations")

    def __oneRightClick(self, event, ldapconnectionobject):
        print("Right clicked mouse on line {}".format(
            event.widget.selection()))
        self.operationsMenu = Menu(self,
                                   tearoff=0,
                                   borderwidth=2,
                                   relief=RAISED)
        self.operationsMenu.add_command(
            label="Refresh tree",
            command=lambda: self.contextOperations(event.widget.selection(
            ), ldapconnectionobject, "REFRESH"))
        self.operationsMenu.add_separator()
        self.operationsMenu.add_command(
            label="Add Entry",
            command=lambda: self.contextOperations(event.widget.selection(
            ), ldapconnectionobject, "ADD"))
        self.operationsMenu.add_command(
            label="Delete Entry",
            command=lambda: self.contextOperations(event.widget.selection(
            ), ldapconnectionobject, "DELETE"))
        self.operationsMenu.add_command(
            label="Move Entry",
            command=lambda: self.contextOperations(event.widget.selection(
            ), ldapconnectionobject, "MOVE"))
        self.operationsMenu.tk_popup(self.treeNavView.winfo_pointerx(),
                                     self.treeNavView.winfo_pointery())

    def __oneLeftClick(self, event, ldapconnectionobject):
        ## Por defecto, click sobre cualquier entrada provoca una busqueda de la misma.
        print("Left clicked mouse on line {}".format(event.widget.selection()))
        dntoSearch = event.widget.selection()
        print(dntoSearch[0])
        ldapoperations.SearchLdap(ldapconnectionobject,
                                  rootSearch=dntoSearch[0],
                                  scopeSearch="BASE")
        self.updateInfoSection(dntoSearch, ldapconnectionobject.response)

    def DisplayAndBind(self, parentID, lineIDX, entryIID, textString,
                       ldapconnectionobject, isOpen):
        self.treeNavView.insert(parentID,
                                lineIDX,
                                entryIID,
                                open=isOpen,
                                text=textString)

        def lefclickhandler(event, self=self, parameters=ldapconnectionobject):
            return self.__oneLeftClick(event, ldapconnectionobject)

        self.treeNavView.bind('<<TreeviewSelect>>', lefclickhandler)

        def rightclickhandler(event,
                              self=self,
                              parameters=ldapconnectionobject):
            return self.__oneRightClick(event, ldapconnectionobject)

        self.treeNavView.bind('<Button-3>', rightclickhandler)

    def ExitOption(self):
        self.quit()

    def OpenConnection(self):
        self.quit()

    def CloseConnection(self):
        self.quit()
Exemple #18
0
class SearchBox(Frame):
    '''A Treeview widget on top, Entry on bottom, using queues for
     interaction with outside functions'''
    def __init__(self, parent=None, db=DB, fdict={}):
        Frame.__init__(self, parent)
        self.Tests = Tests
        self.db = db
        self.fdict = dbm.open(self.db, 'c')
        #self.fdict['**']=''
        self.db_update = False
        #will hold the query to be processed
        self.query = None
        self.drives = self.get_drives()
        self.start_func = StartFunc(
        )  #platform dependent double-click response

        self.results = iter(
            ())  #initiating query results as an empty generator
        self.total_width = self.winfo_screenwidth(
        )  #to adjust column widths relative to screen size
        #Remember scorch mode
        self.scorch = False
        self.encoding = ENCODING

        #for scorch mode
        #self.keylist=self.fdict.keys()
        self.keylist_index = 0
        self.keylist_counter = 0

        #keystroke indicator
        self.counter = 0

        #queues for passing search queries and results
        self.query_queue = Queue()
        self.result_queue = Queue()

        #for usage by db generating function
        self.dbinit_queue = Queue()

        #--Search Results panel at top
        self.panel = Treeview(columns=('Path', 'Size', 'Date'))
        self.panel.pack(expand=True, fill='both')
        self.panel.heading('#0', text='Name')
        self.panel.heading(0, text='Path')
        self.panel.heading(1, text='Size')
        self.panel.heading(2, text='Date Modified')

        #--Starting geometry of the search panel
        try:  #start maximized
            self.panel.master.attributes('-zoomed', 1)
        except:
            self.panel.master.state('zoomed')

        self.panel_width = self.panel.winfo_width()
        #Name - 2/5-----Path - 2/5-----Size -1/25-----Date -4/25
        # '#0' is the 'Name' column
        self.panel.column('#0', width=int(self.total_width * 0.4))
        self.panel.column('Path', width=int(self.total_width * 0.4))
        self.panel.column('Size', width=int(self.total_width * 0.06))
        self.panel.column('Date', width=int(self.total_width * 0.14))

        #--Panel font, style
        self.font = Font(family='Helvetica', size=11)
        '''TkDefaultFont - {'family': 'Segoe UI',  'overstrike': 0, 'size': 9, 
                       'slant': 'roman', 'underline': 0, 'weight': normal'}'''
        self.style = Style()

        #linespace - adjust the row height to the font, doesn't happen on its own in tkinter
        self.style.configure('SearchBox.Treeview',
                             font=self.font,
                             rowheight=self.font.metrics('linespace'))
        self.panel.config(style='SearchBox.Treeview')

        #alternating background colors
        self.panel.tag_configure('color1',
                                 background='gray85')  #, foreground='white')
        self.panel.tag_configure('color2',
                                 background='gray90')  #, foreground='white')
        #'dark sea green', 'wheat3', 'black'

        #--App title and icon, currently transparent
        self.panel.master.title('Jiffy')
        self.icon = PhotoImage(height=16, width=16)
        self.icon.blank()  #transparent icon, works on all but Py35/Win

        #loading the transparent icon. black on Py35/Win
        try:
            self.master.wm_iconphoto('True', self.icon)
        except:
            #For some reason this jammed Python 3.5 with Tk 8.6 on Windows
            self.tk.call('wm', 'iconphoto', self.master._w, self.icon)

        #--A string variable to monitor input to the Entry box
        self.entry_var = StringVar()
        #self.entry_var.set('Type to search. [F5 - Refresh Database]. [F12 - Scorch Mode]')
        # [Ctrl-O - Options]. [Ctrl-I - Info]
        self.entry_var.trace('w', self.update_query)

        #--Entry line on the bottom
        self.entry_box = Entry(textvariable=self.entry_var)
        #keep it as a single line on all window sizes
        self.entry_box.pack(side='bottom', fill='x')

        #--Widget Bindings
        #self.master.bind('<Ctrl-Z>', self.quit)  #alternative to Alt-F4
        self.master.bind('<Control-equal>', self.scaleup)
        self.master.bind('<Control-Button-4>', self.scaleup)
        self.master.bind('<Control-minus>', self.scaledown)
        self.master.bind('<Control-Button-5>', self.scaledown)
        self.master.bind('<Control-MouseWheel>', self.scale_mouse)

        self.panel.bind('<Double-1>', self.doubleclick)
        self.panel.bind('<Return>', self.doubleclick)

        #allow scrolling and typing without switching focus
        self.entry_box.bind('<MouseWheel>', self.scroll_from_entry)
        self.entry_box.bind('<Button-4>', self.scroll_from_entry)
        self.entry_box.bind('<Button-5>', self.scroll_from_entry)

        self.master.bind('<F5>', self.make_database)
        #self.master.bind('<F12>', self.scorch_mode)

        #--Starting up with entry box active
        self.entry_box.focus_set()

        #--Generating a starting message based on existence of a database
        if not self.fdict:
            self.panel.insert('',
                              'end',
                              text='No cache database found',
                              values=('Hit F5 to generate database', ))
        else:
            self.panel.insert(
                '',
                'end',
                text='Type to search.   [F5 - Refresh Database]',
                values=('[Ctrl - +/-/MouseWheel - Adjust font size]', ))
        # [Ctrl-O - Options]. [Ctrl-I - Info]
        #self.panel.insert('', 'end', text='Scorch Mode is faster but uses more memory', values=('Loads the entire database into RAM',))

        self.update_searchbox()
        #Initializing the query managing function in a separate thread (upgrade to pool?)
        thread.start_new_thread(
            TMakeSearch, (self.fdict, self.query_queue, self.result_queue))

    ##GUI functionality--------------------------------------------------------
    #O change to initiation from parameter to SearchBox for more modularity
    def get_drives(event):
        return GetDrives()

    def scroll_from_entry(self, event):
        '''Scroll results without deactivating entry box, called from entry_box'''

        self.panel.yview_scroll(1, 'units')

    def scaleup(self, event):
        '''The Treeview widget won't auto-adjust the row height, 
        so requires manual resetting upon font changing'''
        self.font['size'] += 1
        self.style.configure('SearchBox.Treeview',
                             rowheight=self.font.metrics('linespace') + 1)

    def scaledown(self, event):
        self.font['size'] -= 1
        self.style.configure('SearchBox.Treeview',
                             rowheight=self.font.metrics('linespace') + 1)

    def scale_mouse(self, event):
        self.scaleup(event) if event.delta > 0 else self.scaledown(event)

    def doubleclick(self, event):
        '''Invoke default app on double-click or Enter'''

        #getting file/folder name and removing '[' and ']' for folders
        selection = self.panel.item(self.panel.focus())
        filename = selection['text']
        #remove folder indicating square brackets
        if filename[0] == '[':
            filename = filename[1:-2]

        #SPLIT_TOKEN='\\' if 'win' in sys.platform else '/'
        full_path = selection['values'][0] + SPLIT_TOKEN + filename
        self.start_func(full_path)

    def quit(self, event):
        '''Currently Alt-F4 exits program, in case I want to add more shortcuts.
        Also add thread closing management here'''

        self.master.destroy()

    ##Cheese: update_database()->is_sb_generated(), trace_results(), update_query()
    def make_database(self, event):
        '''Using a thread to generate the dictionary to prevent GUI freezing'''

        #* dbm might not be thread safe - best might be to restart TMakeSearch
        self.gtime = time()  # for testing
        self.entry_var.set('Updating Database')
        self.entry_box.icursor('end')

        #Resulting dicitionay will be passed via dbinint_queue
        thread.start_new_thread(RecursiveCreateDict,
                                (self.drives, self.dbinit_queue, self.fdict))

        #Wait for the dictionary to be generated
        self.is_db_generated()

    def is_db_generated(self):
        '''Update database if available or sleep and try again'''

        if not self.dbinit_queue.empty():
            #A new dictionary was passed

            #retrieving new dict
            self.newdict, self.unsearched = self.dbinit_queue.get()
            #Messaging TMakeSearch to stop querying the dictionary
            self.db_update = True
            self.query_queue.put(None)
            sleep(0.11)  #TMakeSearch takes 0.1s naps. Check further '''

            if whichdb(self.db) == ('dbhash'):
                '''For dumbdbm, this jams the app, as does manual updating. it's
                not dumb, it's just not worthy'''
                self.fdict.update(self.newdict)
            else:
                for key in self.newdict:
                    self.fdict[key] = self.newdict[key]
            print('fdict is created')
            self.db_update = False
            #save new database
            self.fdict.sync()
            print('fdict synced')

            #Open a new TMakeSearch with the updated database
            #thread.start_new_thread(TMakeSearch, (self.fdict, self.query_queue, self.result_queue))

            #Cleaning up
            self.newdict.clear()
            self.newdict = None

            self.gtime = time() - self.gtime
            #to read about {}.format              #also, a label may be simpler
            self.entry_var.set('Database generation time- ' + str(self.gtime) +
                               's. Type to search. [F5 - Refresh Database]')

            #Pass a signal to close TMakeSearch, then reopen it
            self.query_queue.put(True)
            thread.start_new_thread(
                TMakeSearch, (self.fdict, self.query_queue, self.result_queue))

            self.entry_box.icursor(0)
            #self.loading.destroy()
            self.panel.delete(*self.panel.get_children())
            self.panel.insert(
                '',
                0,
                text='Scorch Mode is faster but uses more memory',
                values=('Loads database into RAM', ))
            #self.keylist=fdict.keys()   #for scorch mode
            self.counter = 0
            #self.IS_1ST_PRESS=True
            #for testing
            #print time()-self.start
            #print self.dict_size()
        else:
            self.after(100, self.is_db_generated)

    def update_searchbox(self):
        '''Update GUI with new result batches '''

        self.even = True
        #for splitting size and date from the keys
        self.separator = ' * '.encode(self.encoding)
        while not self.result_queue.empty():
            qresult = self.result_queue.get()
            #print ('is_batch_recieved:', qresult)
            #if qcounter==self.counter:  #currently assuming results will arrive by querying order
            #break
        try:
            #if nothing in queue this will raise an error, saves a preemptive if clause
            self.results, self.is_new = qresult
            if Tests.is_batch_recieved:
                print('is_batch_recieved:', self.results)
        except:
            pass  #no new results
            if Tests.is_batch_recieved:
                print('is_batch_recieved: no new results')
        else:
            #if self.panel.get_children()!=():
            #results for a newer query, erase old results
            if self.is_new:
                self.panel.delete(*self.panel.get_children())

            for key in self.results:
                try:
                    name, size, date = key.decode(self.encoding).split(u'*')
                    #name, size, date=key.split(self.separator)
                    if Tests.is_result_parsed:
                        print(name)
                except:
                    if Tests.is_result_parsed:
                        print('parsing issue with', key)
                else:
                    path = self.fdict[key].decode(self.encoding)
                    '''if 'win' in sys.platform and top[0] is u'/':
                        top=u'C:\\'+top[1:] '''
                    color = 'color1' if self.even else 'color2'
                    self.even = not self.even
                    self.panel.insert('',
                                      'end',
                                      text=name,
                                      values=(path, size, date),
                                      tags=(color, ))

        self.after(60, self.update_searchbox)

    def update_query(self, x=None, y=None, z=None):
        '''Invoked by StringVar().trace() method, which passes 3 arguments that are honorably ditched '''

        #Deactivate while switching dictionaries
        if self.db_update:
            pass

        #Cleaning up for 1st keystroke or after a message in the Entry box
        if not self.counter:
            '''Entry box needs to be cleaned, the new char put in and the cursor
           placed after it'''
            #get&set the 1st search char. user may've changed cursor location b4 typing
            self.entry_var.set(
                self.entry_var.get()[self.entry_box.index(INSERT) - 1])
            #move cursor after the first char
            self.entry_box.icursor(1)

        #counter goes up either way
        self.counter += 1
        self.query = self.entry_var.get()
        self.query_queue.put(self.query)
        if Tests.is_query_sent:
            print(self.query)
            print(self.counter)

    ##Not in use ----------------------------------------------------------------

    def trace_query(self):
        '''If I opt for periodically checking the StringVar'''

        if self.counter:  #when counter=0 there's a message/notification in the entry box
            if self.query != self.entry_var.get():
                self.query = self.entry_var.get()
                self.query_queue.put(self.query)

        self.after(100, self.trace_query)

    def trace_and_update(self):
        ''' In-GUI implementation of query searching, uses a list for iterating 
        over the keys'''
        '''works smoother when results are generated quickly, but with
        sparse results GUI becomes unresponsive for short whiles. Relevant
        only if results are guaranteed to be generated swiftly'''

        #print self.query
        #if new query, resetting search parameters and GUI
        if self.query != self.entry_var.get():
            self.keylist_counter = 0
            self.query = self.entry_var.get()
            self.search_list = self.query.lower().split()
            self.panel.delete(*self.panel.get_children())

        self.insertion_counter = 0
        self.keylist_index = self.keylist_counter
        for key in self.keylist[self.keylist_index:]:
            filename = key.split('*')[0].lower()
            #If a match, parse and add to the Treeview
            if self.all(token in filename for token in self.search_list):
                name, size, date = key.split('*')
                self.panel.insert('',
                                  'end',
                                  text=name,
                                  values=(self.fdict[key], size, date))
                self.insertion_counter += 1
            self.keylist_counter += 1

            if self.insertion_counter >= self.INSERTIONS_PER_CYCLE:  #50  ##or not dict_counter:
                break  #nap time

        self.after(60, self.trace_and_update)
Exemple #19
0
class MyProgram:
    def __init__(self, master):
        self._database = Data()
        self._materias = self._database.consultar('MATERIA')
        self._estudiantes = self._database.consultar('ESTUDIANTE')
        self._carrera = self._database.consultar('CARRERA')
        self._provincia = self._database.consultar('PROVINCIA')
        self._imgfile = 'profileIcon.png'
        self._master = master
        master.title("Sistema de Estudiantes")
        self.menubar = Menu(master)
        self.router_tree_view = ttk.Treeview(self._master)
        #menu 1
        self.estudiantesmenu = Menu(self.menubar, tearoff=0)
        self.estudiantesmenu.add_command(
            label="Consultar", command=lambda: self.consultar("ESTUDIANTE"))
        self.estudiantesmenu.add_command(
            label="Modificar", command=lambda: self.estudianteControl())
        self.menubar.add_cascade(label="Estudiantes",
                                 menu=self.estudiantesmenu)
        #menu 2
        self.materiasmenu = Menu(self.menubar, tearoff=0)
        self.materiasmenu.add_command(
            label="Consultar", command=lambda: self.consultar("MATERIA"))
        self.materiasmenu.add_command(label="Modificar",
                                      command=lambda: self.materiaControl())
        self.menubar.add_cascade(label="Materias", menu=self.materiasmenu)
        #menu 3
        self.calificacionesmenu = Menu(self.menubar, tearoff=0)
        self.calificacionesmenu.add_command(
            label="Consultar",
            command=lambda: self.consultar("CALIFICACIONES"))
        self.calificacionesmenu.add_command(
            label="Modificar", command=lambda: self.calificacionControl())
        self.menubar.add_cascade(label="Calificaciones",
                                 menu=self.calificacionesmenu)
        #menu 4
        self.reportesmenu = Menu(self.menubar, tearoff=0)
        self.reportesmenu.add_command(label="Reporte html",
                                      command=lambda: self.reporteControl())
        self.reportesmenu.add_command(label="Reporte mapa",
                                      command=lambda: self.reporteControlM())
        self.reportesmenu.add_command(label="Reporte grafico",
                                      command=lambda: self.reporteControlG())
        self.menubar.add_cascade(label="Reportes", menu=self.reportesmenu)

        master.config(menu=self.menubar)
        master.geometry("400x300")

    #end _init

    def reporteControl(self):
        idEstudiante = StringVar()
        filewin = Toplevel(self._master)

        Label(filewin, text="Estudiante").place(x=10, y=30)
        CbBoxEstudiante = ttk.Combobox(
            filewin,
            state='readonly',
            textvariable=idEstudiante,
            values=self.get_dataCombo('ESTUDIANTE')).place(x=100, y=30)
        botonReportee = Button(
            filewin,
            text="Reporte html",
            width=14,
            command=lambda: self.reporteH(idEstudiante.get())).place(x=100,
                                                                     y=80)

        filewin.geometry("250x200")
        filewin.mainloop()

    #end method

    def reporteControlM(self):
        idMateria = StringVar()
        idProvincia = StringVar()
        idLitereal = StringVar()
        filewin = Toplevel(self._master)

        Label(filewin, text="Materia").place(x=10, y=30)
        Label(filewin, text="Provincia").place(x=10, y=60)
        Label(filewin, text="Literal").place(x=10, y=90)
        CbBoxEstudiante = ttk.Combobox(
            filewin,
            state='readonly',
            textvariable=idMateria,
            values=self.get_dataCombo('MATERIA')).place(x=100, y=30)
        CbBoxProvincia = ttk.Combobox(
            filewin,
            state='readonly',
            textvariable=idProvincia,
            values=self.get_dataCombo('PROVINCIA')).place(x=100, y=60)
        CbBoxLiteral = ttk.Combobox(filewin,
                                    state='readonly',
                                    textvariable=idLitereal,
                                    values=['A', 'B', 'C', 'D', 'F',
                                            'TODOS']).place(x=100, y=90)
        botonReporte = Button(
            filewin,
            text="Reporte mapa",
            width=14,
            command=lambda: self.reportM(
                [idMateria.get(),
                 idProvincia.get(),
                 idLitereal.get()])).place(x=100, y=130)

        filewin.geometry("250x200")
        filewin.mainloop()

    #end method

    def reporteControlG(self):
        filewin = Toplevel(self._master)

        idprovinciaBarra = StringVar()
        idprovinciaComp1 = StringVar()
        idprovinciaComp2 = StringVar()

        ttk.Combobox(filewin,
                     state='readonly',
                     textvariable=idprovinciaBarra,
                     values=self.get_dataCombo('PROVINCIA')).place(x=170, y=71)
        ttk.Combobox(filewin,
                     state='readonly',
                     textvariable=idprovinciaComp1,
                     values=self.get_dataCombo('PROVINCIA')).place(x=10, y=190)
        ttk.Combobox(filewin,
                     state='readonly',
                     textvariable=idprovinciaComp2,
                     values=self.get_dataCombo('PROVINCIA')).place(x=230,
                                                                   y=190)

        Label(filewin, text="Notas por literales").place(x=10, y=30)
        Label(filewin, text="Literal por provincia").place(x=10, y=70)
        Label(filewin, text="Estudiantes por carrera").place(x=10, y=110)
        Label(filewin, text="Comparativo por provincia").place(x=10, y=150)
        photoLabel = Label(filewin)
        photoLabel.place(x=10, y=230)

        def setPhotoLabel(imagen):
            img = ImageTk.PhotoImage(Image.open(imagen))
            photoLabel.config(image=img)
            photoLabel.photo = img

        # Label(filewin, text="Literal").place(x=10,y=90)
        # CbBoxEstudiante = ttk.Combobox(filewin, state='readonly', textvariable=idMateria, values=self.get_dataCombo('MATERIA')).place(x=100,y=30)
        # CbBoxProvincia = ttk.Combobox(filewin, state='readonly', textvariable=idProvincia, values=self.get_dataCombo('PROVINCIA')).place(x=100,y=60)
        # CbBoxLiteral = ttk.Combobox(filewin,state='readonly', textvariable=idLitereal, values=['A','B','C','D','F','TODOS']).place(x=100,y=90)
        botonReporteL = Button(
            filewin,
            text="Generar",
            width=14,
            command=lambda: self.reportG1(setPhotoLabel)).place(x=170, y=30)
        botonReporteP = Button(
            filewin,
            text="Generar",
            width=10,
            command=lambda: self.reportG2(idprovinciaBarra.get(), setPhotoLabel
                                          )).place(x=330, y=67)
        botonReporteP3d = Button(
            filewin,
            text="Generar en 3D",
            width=10,
            command=lambda: self.reportG5(idprovinciaBarra.get(), setPhotoLabel
                                          )).place(x=420, y=67)
        botonReporteC = Button(
            filewin,
            text="Generar",
            width=14,
            command=lambda: self.reportG3(setPhotoLabel)).place(x=170, y=110)
        botonReporteComp = Button(
            filewin,
            text="Generar",
            width=10,
            command=lambda: self.reportG4(idprovinciaComp1.get(
            ), idprovinciaComp2.get(), setPhotoLabel)).place(x=440, y=186)

        filewin.geometry("600x550")
        filewin.mainloop()

    #end method

    def materiaControl(self, id=0):
        codigo = StringVar()
        nombre = StringVar()
        filewin = Toplevel(self._master)
        Label(filewin, text="Codigo").place(x=10, y=30)
        Label(filewin, text="Nombre").place(x=10, y=60)

        TxtBoxCodigo = Entry(filewin, width=20,
                             textvariable=codigo).place(x=100, y=30)
        TxtBoxNombre = Entry(filewin, width=20,
                             textvariable=nombre).place(x=100, y=60)

        botonInsertar = Button(filewin,
                               text="Insertar",
                               width=14,
                               command=lambda: self.insert_materia(
                                   [codigo.get(), nombre.get()])).place(x=10,
                                                                        y=120)
        # botonModificar=Button(filewin, text = "Modificar", width= 14).place(x=120, y=120)
        # botonBorrar=Button(filewin, text = "Borrar", width= 14,command=lambda:self.greet()).place(x=60, y=160)
        if id != 0:
            data = self._database.consultarById("MATERIA", "CODIGO", id)
            print(data[0])
            codigo.set(data[0])
            nombre.set(data[1])
        #end condition
        filewin.geometry("250x200")
        filewin.mainloop()

    #end method

    def estudianteControl(self, id=0):
        mat = StringVar()
        cedula = StringVar()
        nom = StringVar()
        apellido = StringVar()
        self._imgfile = "profileIcon.png"
        sex = StringVar()
        idcarrera = StringVar()
        idprovincia = StringVar()
        filewin = Toplevel(self._master)
        Label(filewin, text="Cecula").place(x=10, y=30)
        Label(filewin, text="Nombre").place(x=10, y=60)
        Label(filewin, text="Apellido").place(x=10, y=90)
        Label(filewin, text="Sexo").place(x=10, y=120)
        Label(filewin, text="Matricula").place(x=10, y=150)
        Label(filewin, text="Carrera").place(x=10, y=180)
        Label(filewin, text="Provincia").place(x=10, y=210)

        canvas = Canvas(filewin, width=300, height=300).place(x=310, y=60)
        img = ImageTk.PhotoImage(Image.open(self._imgfile))
        photoLabel = Label(filewin, image=img)
        photoLabel.place(x=320, y=60)
        TxtBoxCedula = Entry(filewin, width=20,
                             textvariable=cedula).place(x=100, y=30)
        TxtBoxNombre = Entry(filewin, width=20, textvariable=nom).place(x=100,
                                                                        y=60)
        TxtBoxApellido = Entry(filewin, width=20,
                               textvariable=apellido).place(x=100, y=90)
        TxtBoxSexo = Entry(filewin, width=20, textvariable=sex).place(x=100,
                                                                      y=120)
        TxtBoxMatricula = Entry(filewin, width=20,
                                textvariable=mat).place(x=100, y=150)
        CbBoxCarrera = ttk.Combobox(
            filewin,
            state='readonly',
            textvariable=idcarrera,
            values=self.get_dataCombo('CARRERA')).place(x=100, y=180)
        CbBoxProvincia = ttk.Combobox(
            filewin,
            state='readonly',
            textvariable=idprovincia,
            values=self.get_dataCombo('PROVINCIA')).place(x=100, y=210)

        botonInsertar = Button(filewin,
                               text="Insertar",
                               width=14,
                               command=lambda: self.insert_estudiante([
                                   mat.get(),
                                   nom.get(),
                                   apellido.get(),
                                   cedula.get(), self._imgfile,
                                   sex.get(),
                                   idprovincia.get(),
                                   idcarrera.get()
                               ])).place(x=10, y=240)
        botonConsultar = Button(
            filewin,
            text="Consultar",
            width=10,
            command=lambda: self.estudianteDesdeApi(cedula.get(
            ), [nom, apellido, sex], photoLabel)).place(x=300, y=30)
        #botonModificar=Button(filewin, text = "Modificar", width= 14,).place(x=120, y=120)
        #botonBorrar=Button(filewin, text = "Borrar", width= 14, command= lambda:self.greet()).place(x=60, y=160)
        if id != 0:
            data = self._database.consultarById("ESTUDIANTE", "ID_ESTUDIANTE",
                                                id)
            print(data[0])
            mat.set(data[1])
            nom.set(data[2])
            apellido.set(data[3])
            cedula.set(data[4])
            self._imgfile = data[5]
            raw_data = urllib.request.urlopen(self._imgfile).read()
            img = Image.open(io.BytesIO(raw_data))
            photo = ImageTk.PhotoImage(img)
            photoLabel.config(image=photo)
            photoLabel.photo = photo
            sex.set(data[6])
            idprovincia.set(data[7])
            idcarrera.set(data[8])
        #end condition
        filewin.geometry("450x280")
        filewin.mainloop()

    #end method

    def calificacionControl(self, id=0):
        idEstudiante = StringVar()
        idMateria = StringVar()
        practica1 = StringVar()
        practica2 = StringVar()
        foro1 = StringVar()
        foro2 = StringVar()
        primerParcial = StringVar()
        segundoParcial = StringVar()
        examenFinal = StringVar()
        filewin = Toplevel(self._master)
        Label(filewin, text="Estudiante").place(x=10, y=10)
        Label(filewin, text="Materia").place(x=260, y=10)
        Label(filewin, text="Practica1").place(x=10, y=30)
        Label(filewin, text="Practica2").place(x=10, y=50)
        Label(filewin, text="Foro1").place(x=260, y=30)
        Label(filewin, text="Foro2").place(x=260, y=50)
        Label(filewin, text="Primer Parcial").place(x=10, y=70)
        Label(filewin, text="Segundo Parcial").place(x=10, y=90)
        Label(filewin, text="Examen Final").place(x=260, y=70)

        # TxtBoxEstudiante=Entry(filewin, width=20, textvariable=idEstudiante).place(x=100,y=10)
        CbBoxEstudiante = ttk.Combobox(
            filewin,
            state='readonly',
            textvariable=idEstudiante,
            values=self.get_dataCombo('ESTUDIANTE')).place(x=100, y=10)
        CbBoxMateria = ttk.Combobox(
            filewin,
            state='readonly',
            textvariable=idMateria,
            values=self.get_dataCombo('MATERIA')).place(x=350, y=10)
        # TxtBoxMateria1=Entry(filewin, width=20, textvariable=idMateria).place(x=350,y=10)
        TxtBoxPractica1 = Entry(filewin, width=20,
                                textvariable=practica1).place(x=100, y=30)
        TxtBoxPractica2 = Entry(filewin, width=20,
                                textvariable=practica2).place(x=100, y=50)
        TxtBoxForo1 = Entry(filewin, width=20, textvariable=foro1).place(x=350,
                                                                         y=30)
        TxtBoxForo2 = Entry(filewin, width=20, textvariable=foro2).place(x=350,
                                                                         y=50)
        TxtBoxPrimerParcial = Entry(filewin,
                                    width=20,
                                    textvariable=primerParcial).place(x=100,
                                                                      y=70)
        TxtBoxSegundoParcial = Entry(filewin,
                                     width=20,
                                     textvariable=segundoParcial).place(x=100,
                                                                        y=90)
        TxtBoxExamenfinal = Entry(filewin, width=20,
                                  textvariable=examenFinal).place(x=350, y=70)

        botonInsertar = Button(
            filewin,
            text="Insertar",
            width=14,
            command=lambda: self.insert_calificaciones(id if (
                id != 0) else 0, [idEstudiante.get(),
                                  idMateria.get()], [
                                      practica1.get(),
                                      practica2.get(),
                                      foro1.get(),
                                      foro2.get(),
                                      primerParcial.get(),
                                      segundoParcial.get(),
                                      examenFinal.get()
                                  ])).place(x=100, y=120)
        # botonModificar=Button(filewin, text = "Modificar", width= 14,).place(x=260, y=120)
        # botonBorrar=Button(filewin, text = "Borrar", width= 14,command= lambda:self.greet()).place(x=180, y=160)
        if id != 0:
            data = self._database.consultarById("CALIFICACIONES",
                                                "ID_CALIFICACION", id)
            print(data)
            idEstudiante.set(data[1])
            idMateria.set(data[2])
            practica1.set(data[3])
            practica2.set(data[4])
            foro1.set(data[5])
            foro2.set(data[6])
            primerParcial.set(data[7])
            segundoParcial.set(data[8])
            examenFinal.set(data[9])
        #end condition
        filewin.geometry("500x200")
        filewin.mainloop()

    #end method

    def consultar(self, tabla):
        print(tabla)
        filewin = Toplevel(self._master)
        frame_router = Frame(filewin)
        frame_router.grid(row=4,
                          column=0,
                          columnspan=4,
                          rowspan=6,
                          pady=20,
                          padx=20)
        infoTabla = self._database.infotabla(tabla)
        buscartabla = []
        for campo in infoTabla:
            buscartabla.append(campo[1])
        #end for
        dataTable = self._database.consultar(tabla)
        # print(dataTable[0][0])
        columns = buscartabla
        self.router_tree_view = Treeview(frame_router,
                                         columns=columns,
                                         show="headings")
        self.router_tree_view.bind("<Double-1>", self.itemEvent)
        self.router_tree_view.column(buscartabla[0], width=100)
        for col in columns[0:]:
            self.router_tree_view.column(col, width=120)
            self.router_tree_view.heading(col, text=col)
        #end for
        print(dataTable)
        if type(dataTable) is list:
            i = 0
            for data in dataTable:
                self.router_tree_view.insert(parent='',
                                             index='end',
                                             iid=self.dinamyFill(tabla,
                                                                 data)[0],
                                             values=self.dinamyFill(
                                                 tabla, data))
                i = i + 1
        #end for
        self.router_tree_view.pack(side="left", fill="y")
        scrollbar = Scrollbar(frame_router, orient='vertical')
        scrollbar.configure(command=self.router_tree_view.yview)
        scrollbar.pack(side="right", fill="y")
        self.router_tree_view.config(yscrollcommand=scrollbar.set)
        botonEliminar = Button(
            filewin,
            text="Eliminar",
            width=14,
            command=lambda: self.tableItemDelete(tabla, filewin)).place(x=20,
                                                                        y=250)
        botonEditar = Button(
            filewin,
            text="Editar",
            width=14,
            command=lambda: self.tableItemEdit(tabla, filewin)).place(x=150,
                                                                      y=250)
        filewin.geometry(self.set_dimension(tabla))
        filewin.mainloop()

    #end method

    def dinamyFill(self, tabla, data):
        if tabla == "ESTUDIANTE":
            return (data[0], data[1], data[2], data[3], data[4], data[5],
                    data[6], data[7], data[8])
        elif tabla == "MATERIA":
            return (data[0], data[1])
        elif tabla == "CALIFICACIONES":
            return (data[0], data[1], data[2], data[3], data[4], data[5],
                    data[6], data[7], data[8], data[9])

    #end method

    def set_dimension(self, tabla):
        dimension = "700x300"
        if tabla == "MATERIA":
            dimension = "400x300"
        elif tabla == "CALIFICACIONES":
            dimension = "800x300"
        return dimension

    #end method

    def itemEvent(self):
        item = self.router_tree_view.selection(
        )  #[0] # now you got the item on that tree
        print("you clicked on id", item[0])

    #end method

    def tableItemDelete(self, tabla, f):
        item = self.router_tree_view.selection(
        )  #[0] # now you got the item on that tree
        if len(item) > 0:
            print("you clicked on id", item[0])
            if tabla == "ESTUDIANTE":
                data = self._database.delete(item[0], tabla, 'ID_ESTUDIANTE')
                messagebox.showinfo(title='Informacion', message=data)
                f.destroy()
            elif tabla == 'MATERIA':
                data = self._database.delete(item[0], tabla, 'CODIGO')
                messagebox.showinfo(title='Informacion', message=data)
                f.destroy()
            else:
                data = self._database.delete(item[0], tabla, 'ID_CALIFICACION')
                messagebox.showinfo(title='Informacion', message=data)
                f.destroy()
        else:
            messagebox.showinfo(title='Informacion', message='Seleccione algo')

    #end method

    def tableItemEdit(self, tabla, f):
        item = self.router_tree_view.selection(
        )  #[0] # now you got the item on that tree
        if len(item) > 0:
            print("you clicked on id", item[0])
            if tabla == "ESTUDIANTE":
                f.destroy()
                self.estudianteControl(item[0])
                #print(self._database.delete(item[0], tabla, 'ID_ESTUDIANTE'))
            elif tabla == 'MATERIA':
                f.destroy()
                self.materiaControl(item[0])
                # print(self._database.delete(item[0], tabla, 'CODIGO'))
            else:
                f.destroy()
                self.calificacionControl(item[0])
                # print(self._database.delete(item[0], tabla, 'ID_CALIFICACION'))
        else:
            messagebox.showinfo(title='Informacion', message='Seleccione algo')

    #end method

    def insert_estudiante(self, values):
        dic = {'data': values, 'notas': [0, 0, 0, 0, 0, 0, 0]}
        alumno = Alumno(dic)
        print('data antes', dic['data'])
        if alumno.is_valid():
            data = self._database.insert(
                [(dic['data'][0], dic['data'][0], dic['data'][1],
                  dic['data'][2], dic['data'][3], dic['data'][4],
                  dic['data'][5], dic['data'][6], dic['data'][7])],
                'ESTUDIANTE', 9)
            messagebox.showinfo(title='Informacion', message=data)
            self._estudiantes = self._database.consultar('ESTUDIANTE')
        else:
            messagebox.showinfo(title='Informacion',
                                message='Datos no validos')

    #end method

    def insert_materia(self, values):
        if values[0] != "" and values[0] != "":
            data = self._database.insert([(values[0], values[1])], 'MATERIA',
                                         2)
            messagebox.showinfo(title='Informacion', message=data)
            self._materias = self._database.consultar('MATERIA')
        else:
            messagebox.showinfo(title='Informacion',
                                message='Datos no validos')

    #end method

    def insert_calificaciones(self, editing, info, values):
        # dic = {'data':['','',''],'notas':values}
        ncalif = self._database.calificacionByEstudiante(info[0])
        print(len(ncalif))
        nota = Notas(values)
        print(info)
        print(values)
        now = datetime.now()
        timestamp = datetime.timestamp(now)
        id = str(timestamp)
        if nota.is_valid(
        ) and info[0] != "" and info[1] != '' and len(ncalif) < 4:
            data = self._database.insert(
                [(editing if (editing != 0) else id[11:17], info[0], info[1],
                  values[0], values[1], values[2], values[3], values[4],
                  values[5], values[6])], "CALIFICACIONES", 10)
            messagebox.showinfo(title='Informacion', message=data)
        else:
            messagebox.showinfo(title='Informacion',
                                message='Ya tiene 3 materias.' if
                                (len(ncalif) == 3) else 'Datos no validos')

    #end method

    def estudianteDesdeApi(self, cedula, inputsFields, photoLabel):
        if (cedula != ""):
            respuestaServicio = Services(cedula).get_datos()
            #manejo de service fail
            print('aqui', respuestaServicio)
            if respuestaServicio['ok'] != False:
                if "Cedula" in respuestaServicio:
                    print(respuestaServicio)
                    inputsFields[0].set(respuestaServicio['Nombres'])
                    inputsFields[1].set(
                        f"{respuestaServicio['Apellido1']} {respuestaServicio['Apellido2']}"
                    )
                    inputsFields[2].set(respuestaServicio['IdSexo'])
                    print(respuestaServicio["foto"])
                    self._imgfile = respuestaServicio["foto"]
                    raw_data = urllib.request.urlopen(self._imgfile).read()
                    img = Image.open(io.BytesIO(raw_data))
                    photo = ImageTk.PhotoImage(img)
                    photoLabel.config(image=photo)
                    photoLabel.photo = photo
                    print(photo)
                    #image = ImageTk.PhotoImage(im)
                # else:
                #     messagebox.showinfo(title='Informacion', message='Cedula no encontrada')
            else:
                messagebox.showinfo(
                    title='Informacion',
                    message='Ha ocurrido un error, intente otra cedula.')
        else:
            messagebox.showinfo(title='Informacion',
                                message='Cedula no valida.')

    #end method

    def greet(self):
        messagebox.showinfo(title='Informacion', message='Greetings!')

    #end methhod

    def get_dataCombo(self, tabla):
        data = []
        values = self._estudiantes
        if tabla == 'MATERIA':
            values = self._materias
        elif tabla == 'CARRERA':
            values = self._carrera
        elif tabla == 'PROVINCIA':
            values = self._provincia
        i = 0
        for v in values:
            data.append(v[1] if (
                tabla == 'PROVINCIA' or tabla == 'CARRERA') else v[0])
            i = i + 1
        return data

    #end method

    def reporteH(self, m):
        print(m)
        report = Reporte(m)
        report.get_report()

    #end method

    def reportM(self, values):
        #0 materi 1 provincia 2 literal
        if values[0] != "" and values[1] != "" and values[2] != "":
            report = Reporte('20202020')
            report.get_reportM(values)
        else:
            messagebox.showinfo(title='Informacion',
                                message='Seleccione los campos.')

    #end method

    def reportG3(self, setPhotoLabel):
        values = self._database.estudianteByCarrera()
        # values=[(1, 'Ingeniería de software'), (2, 'Ingeniería industrial')]
        value = []
        legend = []
        for i in values:
            value.append(i[0])
            legend.append(i[1])
        report = Reporte('20202020')
        # values=['tipo',[0,2,4],['juan','pedro'],'title','colum','values']
        data = ['pastel', value, legend, 'Estudiantes por carreras']
        report.get_reportG(data)
        setPhotoLabel("pastel.png")

    #end method

    def reportG1(self, setPhotoLabel):
        n = self._database.consultar('CALIFICACIONES')
        letras = {'A': 0, 'B': 0, 'C': 0, 'D': 0, 'F': 0}
        for i in n:
            nota = Notas([i[3], i[4], i[5], i[6], i[7], i[8], i[9]])
            cal = Calculo(nota)
            for f in letras:
                if f == cal.get_literal():
                    letras[f] = letras[f] + 1
        print(letras)
        report = Reporte('20202020')
        # values=['tipo',[0,2,4],['juan','pedro'],'title','colum','values']
        value = [i for i in letras]
        legend = [letras[i] for i in letras]
        data = [
            'barra', value, legend, 'Notas por literal', 'Literal', 'Cantidad'
        ]
        report.get_reportG(data)
        setPhotoLabel("barra.png")

    #end method

    def reportG5(self, idProvincia, setPhotoLabel):
        if (idProvincia):
            n = self._database.literalesByProvincia()
            graphData = self.filterLiteralsByProvince(idProvincia, n)
            report = Reporte('20202020')
            data = [
                'barra3D', graphData[0], graphData[1],
                f'Notas en {idProvincia}', 'Literal', 'Cantidad'
            ]
            report.get_reportG(data)
            setPhotoLabel("barra3D.png")
        else:
            messagebox.showinfo(title='Informacion',
                                message='Seleccione una provincia')

    #end method

    def reportG2(self, idProvincia, setPhotoLabel):
        if (idProvincia):
            n = self._database.literalesByProvincia()
            graphData = self.filterLiteralsByProvince(idProvincia, n)
            report = Reporte('20202020')
            data = [
                'barra', graphData[0], graphData[1], f'Notas en {idProvincia}',
                'Literal', 'Cantidad'
            ]
            report.get_reportG(data)
            setPhotoLabel("barra.png")
        else:
            messagebox.showinfo(title='Informacion',
                                message='Seleccione una provincia')

    #end method
    def filterLiteralsByProvince(self, idProvincia, grade):
        letras = {'A': 0, 'B': 0, 'C': 0, 'D': 0, 'F': 0}
        for i in grade:
            if (i[10] == idProvincia):
                nota = Notas([i[3], i[4], i[5], i[6], i[7], i[8], i[9]])
                cal = Calculo(nota)
                for f in letras:
                    if f == cal.get_literal():
                        letras[f] = letras[f] + 1
        value = [i for i in letras]
        legend = [letras[i] for i in letras]
        return [value, legend]

    def reportG4(self, idProvincia1, idProvincia2, setPhotoLabel):
        if (idProvincia1 and idProvincia2):
            values = self._database.literalesByProvincia()
            graphData1 = self.filterLiteralsByProvince(idProvincia1, values)
            graphData2 = self.filterLiteralsByProvince(idProvincia2, values)
            provincias = [idProvincia1, idProvincia2]
            report = Reporte('20202020')
            data = [
                'Comparativo', graphData1, graphData2, 'Grafico Comparativo',
                provincias
            ]
            report.get_reportG(data)
            setPhotoLabel("Comparativo.png")
        else:
            messagebox.showinfo(title='Informacion',
                                message='Seleccione las provincias')
Exemple #20
0
class Report(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.root = self.winfo_toplevel()
        self.root.title(" ".join((APPNAME, VERSION, "| Report")))
        self.root.resizable(0, 0)
        self.items = None
        headers = ('Page', 'Rank', 'PageRank Value', 'Incoming')
        self.t = Scale(self,
                       from_=0,
                       to=1,
                       label='n-th iteration',
                       bd=1,
                       width=7,
                       orient='horizontal',
                       command=self.__set_t)
        self.t.pack(fill='x')
        self.label = Label(self, anchor='e')
        self.label.pack(fill='x')
        self.tree = Treeview(self,
                             columns=headers,
                             show="headings",
                             height=REPORT_HEIGHT)
        self.tree.column(0, anchor='center', width=55)
        self.tree.column(1, anchor='center', width=55)
        self.tree.column(2, width=175)
        self.tree.column(3, anchor='center', width=55)
        self.scroll = Scrollbar(self, command=self.tree.yview)
        self.scroll.pack(side='right', fill='y')
        self.tree.config(yscrollcommand=self.scroll.set)
        for col in headers:
            self.tree.heading(col, text=col.title())
        self.root.master.focus_force()
        self.root.bind('<Key>', self.__keys)

    def __keys(self, event):
        if event.char == 'i':
            self.t.set(self.t.get() - 1)
        elif event.char == 'I':
            self.t.set(0)
        elif event.char == 'o':
            self.t.set(self.t.get() + 1)
        elif event.char == 'O':
            self.t.set(self.pagerank[1])

    def __set_t(self, t=None):
        self.render(self.pagerank, self.edge_counts, self.d, self.e, t=int(t))

    def render(self, pagerank, edge_counts, d, e, t=None):
        self.d, self.e = d, e
        self.edge_counts = edge_counts
        self.pagerank = pagerank
        if t is not None:
            pr = pagerank[0][t]
        else:
            self.t.config(command=None)
            self.t.config(to=self.pagerank[1])
            self.t.set(self.pagerank[1])
            self.t.config(command=self.__set_t)
            pr = pagerank[0][-1]
        label_text = '# of ranks:{0:>3}     # of iterations:{1:>3}'.format(
            len(set(pr.values())), self.pagerank[1])
        self.label.config(text=label_text)
        in_map = {k: 0 for k in pr.keys()}  # incoming edges by nodes
        for (tail, head), n in edge_counts.items():
            if tail is not head:
                in_map[head] += n

        get_rank = lambda k: sorted(pr.values())[::-1].index(pr[k]) + 1
        data = tuple(
            (k, get_rank(k), pr[k], in_map[k]) for k in sorted(pr.keys()))
        if self.items: self.tree.delete(*self.items)
        self.items = [
            self.tree.insert('', 'end', values=line) for line in data
        ]
        self.tree.pack(side='left', fill='y')
        #self.root.master.focus_force()

    def destroy(self):
        super().destroy()
        self.root.master.r_win = False
        self.root.master.windowsmenu.entryconfig(0, label='[ ] Report window')
        self.root.destroy()
Exemple #21
0
class Configurator(tk.Tk):
    """
    The main Tk window representing the main app.
    
    Attributes
    ---------- 
    treeview :  :py:class:`~tkinter.Treeview`
        The treeview widget.
    treeview_popup_target_id : `int`
        The pop target id relating to the id of the selected element.
    treeview_popup : :py:class:`~tkinter.Widget`
        The treeview popup widget.
    cfg_file_name : `str`
        The file name of the current configuration.
    element_dict : `dict`
        The dictionary of elements. Keys are the element ids.
    root_element : :py:class:`~enrich2.base.storemanager.StoreManager`
        An instance inheriting from storemanager that acts as a root object.
    force_recalculate :py:class:`tkinter.BooleanVar`
        The tkinter boolean variable for this option.
    component_outliers :py:class:`tkinter.BooleanVar`
        The tkinter boolean variable for this option.
    tsv_requested : :py:class:`tkinter.BooleanVar`
        The tkinter boolean variable for this option.
    treeview_buttons : `list`
        The ``new``, ``edit`` and ``delete`` buttons.
    go_button : :py:class`~tkinter.ttk.Button`
        The button that begins the analysis
    scorer_widget : :py:class:`~enrich2.gui.options_frame.ScorerScriptsDropDown`
        The ScorerScriptsDropDown instance associated with this app.
    scorer : :py:class:`~enrich2.plugins.scoring.BaseScorerPlugin`
        The scorer class loaded from a plugin
    scorer_attrs : `dict`
        The scoring attributes for the plugin.
    scorer_path : `str`
        The path to the currently selected scoring plugin.
    analysis_thread : :py:class:`~threading.Thread`
        The thread object that runs the computation method to prevent 
        GUI blocking.
    
    Methods
    -------
    create_main_frame
    create_menubar
    create_treeview_context_menu
    create_new_element
    
    menu_open
    menu_save
    menu_saveas
    menu_selectall
    
    refresh_treeview
    treeview_context_menu
    set_treeview_properties
    populate_tree
    go_button_press
    new_button_press
    edit_button_press
    delete_button_press
    delete_element
    apply_seqlib_fastq
    
    get_element
    get_focused_element
    get_selected_elements
    get_selected_scorer_class
    get_selected_scorer_attrs
    get_selected_scorer_path
    
    run_analysis
    set_gui_state
    configure_analysis
    
    refresh_plugins
    show_plugin_source_window

    See Also
    --------
    :py:class:`~tkinter.Tk`
    
    """
    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Enrich 2")

        # Main app variables
        self.cfg_file_name = tk.StringVar()
        self.element_dict = dict()
        self.root_element = None
        self.analysis_thread = None
        self.plugin_source_window = None
        self.queue = queue.Queue()

        # Treeview variables
        self.treeview = None
        self.treeview_popup_target_id = None
        self.treeview_popup = None

        # analysis options
        self.force_recalculate = tk.BooleanVar()
        self.component_outliers = tk.BooleanVar()
        self.tsv_requested = tk.BooleanVar()

        # allow resizing
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        # create UI elements
        self.treeview_buttons = []
        self.go_button = None
        self.scorer_widget = None
        self.scorer = None
        self.scorer_attrs = None
        self.scorer_path = None
        self.create_main_frame()
        self.create_menubar()
        self.create_treeview_context_menu()
        self.after(10, self.poll_logging_queue)

        self.plugin_source_window = SourceWindow(master=self)
        self.plugin_source_window.hide()
        self.refresh_plugins()

    # ---------------------------------------------------------------------- #
    #                           Creation Methods
    # ---------------------------------------------------------------------- #
    def create_treeview_context_menu(self):
        """
        This creates the tree-like view rendering the experiment heirachy.
        """
        self.treeview_popup = tk.Menu(self, tearoff=0)
        self.treeview_popup.add_command(label="Apply FASTQ...",
                                        command=self.apply_seqlib_fastq)

    def create_main_frame(self):
        """
        Large function creating all the basic elements of the main app frame.
        Creates the treeview and associated buttons, the scoring plugin frame
        and the go button.
        """
        # Frame for the Treeview and New/Edit/Delete buttons
        main = Frame(self, padding=(3, 3, 12, 12))
        main.rowconfigure(0, weight=1)
        main.columnconfigure(0, weight=1)
        main.columnconfigure(1, weight=0)
        main.grid(row=0, column=0, sticky="nsew")

        # ------------------------------------------------------- #
        # Frame for the Treeview and its scrollbars
        tree_frame = Frame(main, padding=(3, 3, 12, 12))
        tree_frame.rowconfigure(0, weight=1)
        tree_frame.rowconfigure(1, weight=0)
        tree_frame.columnconfigure(0, weight=1)
        tree_frame.columnconfigure(1, weight=0)
        tree_frame.grid(row=0, column=0, sticky="nsew")

        # ------------------------------------------------------- #
        # Treeview with column headings
        self.treeview = Treeview(tree_frame)
        self.treeview["columns"] = ("class", "barcodes", "variants")
        self.treeview.column("class", width=120)
        self.treeview.heading("class", text="Type")
        self.treeview.column("barcodes",
                             width=25,
                             stretch=tk.NO,
                             anchor=tk.CENTER)
        self.treeview.heading("barcodes", text="BC")
        self.treeview.column("variants",
                             width=25,
                             stretch=tk.NO,
                             anchor=tk.CENTER)
        self.treeview.heading("variants", text="V")
        self.treeview.grid(row=0, column=0, sticky="nsew")

        # Treeview context menu bindings
        self.treeview.bind("<Button-2>", self.treeview_context_menu)

        # Treeview scrollbars
        tree_ysb = tk.Scrollbar(tree_frame,
                                orient="vertical",
                                command=self.treeview.yview)
        tree_xsb = tk.Scrollbar(tree_frame,
                                orient="horizontal",
                                command=self.treeview.xview)
        tree_ysb.grid(row=0, column=1, sticky="nsw")
        tree_xsb.grid(row=1, column=0, sticky="ewn")
        self.treeview.config(yscroll=tree_ysb.set, xscroll=tree_xsb.set)

        # ------------------------------------------------------- #
        # Frame for New/Edit/Delete buttons
        button_frame = Frame(main, padding=(3, 3, 12, 12))
        button_frame.grid(row=1, column=0)
        new_button = Button(button_frame,
                            text="New...",
                            command=self.new_button_press)
        new_button.grid(row=0, column=0)
        edit_button = Button(button_frame,
                             text="Edit...",
                             command=self.edit_button_press)
        edit_button.grid(row=0, column=1)
        delete_button = Button(button_frame,
                               text="Delete",
                               command=self.delete_button_press)
        delete_button.grid(row=0, column=2)

        self.treeview_buttons = [new_button, delete_button, edit_button]

        # ------------------------------------------------------- #
        # Frame for Plugin and Analysis Options
        right_frame = Frame(main, padding=(3, 3, 12, 12))
        right_frame.rowconfigure(0, weight=1)
        right_frame.rowconfigure(1, weight=0)
        right_frame.columnconfigure(0, weight=1)
        right_frame.columnconfigure(1, weight=0)
        right_frame.grid(row=0, column=1, sticky="new")

        # ------------------------------------------------------- #
        # LabelFrame for plugin and options
        scoring_plugin = ScorerScriptsDropDown(right_frame,
                                               text="Scoring Options",
                                               padding=(3, 3, 12, 12))
        scoring_plugin.grid(row=0, column=0, sticky="new")
        self.scorer_widget = scoring_plugin

        # ------------------------------------------------------- #
        # LabelFrame for Analysis Options
        row = 0
        options_frame = LabelFrame(right_frame,
                                   text="Analysis Options",
                                   padding=(3, 3, 12, 12))
        options_frame.grid(row=1, column=0, sticky="new", pady=4)

        # force recalculate
        force_recalculate = Checkbutton(options_frame,
                                        text="Force Recalculation",
                                        variable=self.force_recalculate)
        force_recalculate.grid(column=0, row=row, sticky="w")
        row += 1

        # component outliers
        component_outliers = Checkbutton(
            options_frame,
            text="Component Outlier Statistics",
            variable=self.component_outliers,
        )
        component_outliers.grid(column=0, row=row, sticky="w")
        row += 1

        # write tsv
        tsv_requested = Checkbutton(options_frame,
                                    text="Write TSV Files",
                                    variable=self.tsv_requested)
        tsv_requested.grid(column=0, row=row, sticky="w")
        tsv_requested.invoke()
        row += 1

        # ------------------------------------------------------- #
        # Run Analysis button frame
        go_button_frame = Frame(main, padding=(3, 3, 12, 12))
        go_button_frame.grid(row=1, column=1)
        go_button = Button(go_button_frame,
                           text="Run Analysis",
                           command=self.go_button_press)
        go_button.grid(column=0, row=0)
        self.go_button = go_button

    def create_new_element(self):
        """
        Create and return a new element based on the current selection.

        This element is not added to the treeview. 
        """
        element = None
        parent_element = self.get_focused_element()
        if isinstance(parent_element, Experiment):
            element = Condition()
            element.parent = parent_element
        elif isinstance(parent_element, Condition):
            element = Selection()
            element.parent = parent_element
        elif isinstance(parent_element, Selection):
            element = CreateSeqLibDialog(self).element_type()
            element.parent = parent_element
        elif isinstance(parent_element, SeqLib):
            # special case: creates a copy of the selected SeqLib as a sibling
            element = type(parent_element)()
            element.configure(parent_element.serialize())
            element.parent = parent_element.parent
            # clear out the seqlib-specific values
            element.name = None
            element.timepoint = None
            element.counts_file = None
            element.reads = None
        else:
            raise ValueError("Unrecognized parent object "
                             "type '{}'".format(type(parent_element)))
        return element

    def create_menubar(self):
        """
        Creates the menubar for the main app, with associated drop down menus.
        """
        # make platform-specific keybinds
        if platform.system() == "Darwin":
            accel_string = "Command+"
            accel_bind = "Command-"
        else:
            accel_string = "Ctrl+"
            accel_bind = "Control-"

        # create the menubar
        menubar = tk.Menu(self)

        # file menu
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(
            label="Open...",
            accelerator="{}O".format(accel_string),
            command=self.menu_open,
        )
        filemenu.add_command(label="Save",
                             accelerator="{}S".format(accel_string),
                             command=self.menu_save)
        filemenu.add_command(
            label="Save As...",
            accelerator="{}Shift+S".format(accel_string),
            command=self.menu_saveas,
        )
        menubar.add_cascade(label="File", menu=filemenu)

        # edit menu
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(
            label="Select All",
            accelerator="{}A".format(accel_string),
            command=self.menu_selectall,
        )
        menubar.add_cascade(label="Edit", menu=filemenu)

        # tools menu
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(
            label="Show Log",
            accelerator="{}L".format(accel_string),
            command=show_log_window,
        )
        filemenu.add_command(
            label="Plugin Sources",
            accelerator="{}P".format(accel_string),
            command=self.show_plugin_source_window,
        )
        filemenu.add_command(
            label="Refresh Plugins",
            accelerator="{}R".format(accel_string),
            command=self.refresh_plugins,
        )
        menubar.add_cascade(label="Tools", menu=filemenu)

        # add the menubar
        self.config(menu=menubar)

        # add file menu keybinds
        self.bind("<{}o>".format(accel_bind), lambda event: self.menu_open())
        self.bind("<{}s>".format(accel_bind), lambda event: self.menu_save())
        self.bind("<{}Shift-s>".format(accel_bind),
                  lambda event: self.menu_saveas())

        # add edit menu keybinds
        self.bind("<{}a>".format(accel_bind),
                  lambda event: self.menu_selectall())

        # add show log menu keybinds
        # add edit menu keybinds
        self.bind("<{}l>".format(accel_bind), lambda event: show_log_window())
        self.bind("<{}p>".format(accel_bind),
                  lambda event: self.show_plugin_source_window())
        self.bind("<{}r>".format(accel_bind),
                  lambda event: self.refresh_plugins())

    # ---------------------------------------------------------------------- #
    #                          Treeview Methods
    # ---------------------------------------------------------------------- #
    def treeview_context_menu(self, click):
        """
        Sets the currently selected treeview object id in the variable
        ``treeview_popup_target_id``.
        
        Parameters
        ----------
        click : 
            tkinter click event
        """
        target = self.treeview.identify_row(click.y)
        if target != "":
            self.treeview_popup_target_id = target
            self.treeview_popup.post(click.x_root, click.y_root)
        self.treeview_popup_target_id = None

    def apply_seqlib_fastq(self):
        """
        Applies settings to the seqlib object by running the configuration
        method.
        """
        SeqLibApplyDialog(self, self, self.treeview_popup_target_id)

    def new_button_press(self):
        """
        Spawns a dialog box depending on the currently selected treeview item
        to create a new element.
        """
        if self.treeview.focus() == "" and self.root_element is not None:
            tkinter.messagebox.showwarning(None, "No parent element selected.")
        else:
            if self.treeview.focus() == "" and self.root_element is None:
                element = CreateRootDialog(self).element
                if isinstance(element, SeqLib):
                    EditDialog(self, self, element)
                self.root_element = element
            else:
                element = self.create_new_element()
                EditDialog(self, self, element)

            # refresh the treeview and re-assign treeview id's
            self.refresh_treeview()

            # select the newly added element if it was successfully added
            if element.treeview_id in list(self.element_dict.keys()):
                self.treeview.focus(element.treeview_id)
                self.treeview.selection_set(element.treeview_id)
            else:
                if element.parent is not None:
                    self.treeview.focus(element.parent.treeview_id)
                    self.treeview.selection_set(element.parent.treeview_id)
                del element

    def edit_button_press(self):
        """
        Spawns a dialog box depending on the currently selected treeview item
        to edit the selected element.
        """
        if self.treeview.focus() == "":
            tkinter.messagebox.showwarning(None, "No element selected.")
        else:
            EditDialog(self, self, self.get_focused_element())

    def delete_button_press(self):
        """
        Deletes the selected treeview element and it's children.
        """
        if self.treeview.focus() == "":
            tkinter.messagebox.showwarning(None, "No element selected.")
        else:
            DeleteDialog(self, self)

    def delete_element(self, tree_id):
        """
        Delete element with Treeview id *tree_id* from the tree, from the 
        element dictionary, and from the associated data structure. Recursively 
        deletes all children of *tree_id*.

        The tree should be refreshed using :py:meth:`refresh_tree` after 
        each deletion. This is the responsibility of the caller.

        Parameters
        ----------
        tree_id : `int`
            The id of the currently selected treeview element.

        """
        if tree_id in self.element_dict:
            # recursively delete children
            if self.element_dict[tree_id].children is not None:
                for child in self.element_dict[tree_id].children:
                    self.delete_element(child.treeview_id)

            # check if deleting the root element
            if self.root_element.treeview_id == tree_id:
                # clear the root element
                print("None {}".format(tree_id))
                self.root_element = None
            else:
                try:
                    # remove the element from its parent's list of children
                    self.element_dict[tree_id].parent.remove_child_id(tree_id)
                except AttributeError:
                    raise AttributeError(
                        "Non-root element lacks proper parent")

            # delete the element from the dictionary
            del self.element_dict[tree_id]

    def refresh_treeview(self):
        """
        Clears the Treeview and repopulates it with the 
        current contents of the tree.
        """
        # clear the entries in the Treeview
        for x in self.treeview.get_children():
            self.treeview.delete(x)

        # clear the id-element dictionary
        # elements may be given new id's after repopulation
        self.element_dict.clear()

        # repopulate
        if self.root_element is not None:
            self.populate_tree(self.root_element)

    def set_treeview_properties(self, element):
        """
        Set the information text for the Treeview *element*.

        Parameters
        ----------
        element : :py:class:`~enrich2.base.storemanager.StoreManager`
            The storemanager object to configure.
        """
        # set class property
        self.treeview.set(element.treeview_id, "class",
                          element.treeview_class_name)

        # add the check marks for barcodes/variants
        if "variants" in element.labels:
            self.treeview.set(element.treeview_id, "variants", u"\u2713")
        else:
            self.treeview.set(element.treeview_id, "variants", "")
        if "barcodes" in element.labels:
            self.treeview.set(element.treeview_id, "barcodes", u"\u2713")
        else:
            self.treeview.set(element.treeview_id, "barcodes", "")

        self.treeview.set(element.treeview_id, "class",
                          element.treeview_class_name)

    def populate_tree(self, element, parent_id=""):
        """
        Recursively populate the Treeview.

        Also populates the *id_cfgstrings*.

        Parameters
        ----------
        element : :py:class:`~enrich2.base.storemanager.StoreManager`
            The storemanager object to configure.
        parent_id : `int`
            ``treeview_id`` of element's parent.
        """
        # insert into the Treeview
        element.treeview_id = self.treeview.insert(parent_id,
                                                   "end",
                                                   text=element.name,
                                                   open=True)
        # add id-element pair to dictionary
        self.element_dict[element.treeview_id] = element
        # set information fields
        self.set_treeview_properties(element)

        # populate for children
        if element.children is not None:
            for child in element.children:
                self.populate_tree(child, parent_id=element.treeview_id)

    # ---------------------------------------------------------------------- #
    #                          Getter Methods
    # ---------------------------------------------------------------------- #
    def get_selected_scorer_class(self):
        """
        Returns the currently selected scoring class object.
        """
        return self.scorer

    def get_selected_scorer_attrs(self):
        """
        Returns the currently selected scoring class attribute `dict`.
        """
        return self.scorer_attrs

    def get_selected_scorer_path(self):
        """
        Returns the currently selected scoring path.
        """
        return self.scorer_path

    def get_element(self, treeview_id):
        """
        Returns the element with *treeview_id*.

        Parameters
        ----------
        treeview_id : `int`
            ``treeview_id`` attribute of element to get.

        Returns
        -------
        :py:class:`~enrich2.base.storemanager.StoreManager`
            The instance with matching ``treeview_id``

        """
        return self.element_dict[treeview_id]

    def get_focused_element(self):
        """
        Gets the focused element in the treeview.

        Returns
        -------
        :py:class:`~enrich2.base.storemanager.StoreManager`
            Returns the element that is currently being focused in the 
            Treeview. ``None`` if nothing is focused.
        """
        if self.treeview.focus() != "":
            return self.get_element(self.treeview.focus())
        else:
            return None

    def get_selected_elements(self):
        """
        Returns a list of currently selected elements in the treeview.

        Returns
        -------
        `list`
            Returns a list of elements that are currently selected in the 
            Treeview. If no elements are selected, it returns an empty list.

        """
        return [self.get_element(x) for x in self.treeview.selection()]

    # ---------------------------------------------------------------------- #
    #                          Menubar Methods
    # ---------------------------------------------------------------------- #
    def menu_open(self):
        """
        Spawns an `askopenfilename` dialog to open a configuration file.
        """
        message_title = "Open Configuration"
        fname = tkinter.filedialog.askopenfilename()
        if len(fname) > 0:  # file was selected
            try:
                with open(fname, "rU") as handle:
                    cfg = json.load(handle)
            except ValueError:
                tkinter.messagebox.showerror(message_title,
                                             "Failed to parse config file.")
            except IOError:
                tkinter.messagebox.showerror(message_title,
                                             "Could not read config file.")
            else:
                if is_experiment(cfg):
                    obj = Experiment()
                elif is_selection(cfg):
                    obj = Selection()
                elif is_seqlib(cfg):
                    sltype = seqlib_type(cfg)
                    obj = globals()[sltype]()
                else:
                    tkinter.messagebox.showerror(
                        message_title, "Unrecognized config format.")
                    return
                obj.output_dir_override = False
                try:
                    if isinstance(obj, Experiment) or isinstance(
                            obj, Selection):
                        obj.configure(cfg, init_from_gui=True)
                    else:
                        obj.configure(cfg)

                    # Try load the scorer into the GUI
                    scorer_path = cfg.get(SCORER, {}).get(SCORER_PATH, "")
                    scorer_attrs = cfg.get(SCORER, {}).get(SCORER_OPTIONS, {})
                    if scorer_path:
                        self.scorer_widget.load_from_cfg_file(
                            scorer_path, scorer_attrs)
                    else:
                        log_message(
                            logging_callback=logging.warning,
                            msg="No plugin could be loaded from configuration.",
                            extra={"oname": self.__class__.__name__},
                        )

                except Exception as e:
                    tkinter.messagebox.showerror(
                        message_title,
                        "Failed to load config file:\n\n{}".format(e))
                else:
                    self.root_element = obj
                    self.cfg_file_name.set(fname)
                    self.refresh_treeview()

    def menu_save(self):
        """
        Asks the user where to save the current configuration.
        """
        if len(self.cfg_file_name.get()) == 0:
            self.menu_saveas()
        elif self.root_element is None:
            tkinter.messagebox.showwarning("Save Configuration",
                                           "Cannot save empty configuration.")
        else:
            save = askyesno("Save Configuration",
                            "Overwrite existing configuration?")
            if not save:
                return
            try:
                with open(self.cfg_file_name.get(), "w") as handle:
                    cfg = self.root_element.serialize()

                    # Get the currently selected scorer
                    if not isinstance(self.root_element,
                                      SeqLib) and not isinstance(
                                          self.root_element, Condition):
                        (
                            _,
                            attrs,
                            scorer_path,
                        ) = self.scorer_widget.get_scorer_class_attrs_path()
                        cfg[SCORER] = {
                            SCORER_PATH: scorer_path,
                            SCORER_OPTIONS: attrs
                        }
                    write_json(cfg, handle)
            except IOError:
                tkinter.messagebox.showerror("Save Configuration",
                                             "Failed to save config file.")
            else:
                tkinter.messagebox.showinfo(
                    "Save Configuration",
                    "Saved file at location:\n\n{}".format(
                        self.cfg_file_name.get()),
                )

    def menu_saveas(self):
        """
        Asks the user where to save the current configuration.
        """
        if self.root_element is None:
            tkinter.messagebox.showwarning("Save Configuration",
                                           "Cannot save empty configuration.")
        else:
            fname = tkinter.filedialog.asksaveasfilename()
            if len(fname) > 0:  # file was selected
                try:
                    with open(fname, "w") as handle:
                        cfg = self.root_element.serialize()

                        # Get the currently selected scorer
                        if not isinstance(self.root_element,
                                          SeqLib) and not isinstance(
                                              self.root_element, Condition):
                            (
                                _,
                                attrs,
                                scorer_path,
                            ) = self.scorer_widget.get_scorer_class_attrs_path(
                            )
                            cfg[SCORER] = {
                                SCORER_PATH: scorer_path,
                                SCORER_OPTIONS: attrs,
                            }
                        write_json(cfg, handle)
                except IOError:
                    tkinter.messagebox.showerror(
                        "Save Configuration", "Failed to save config file.")
                else:
                    self.cfg_file_name.set(fname)
                    tkinter.messagebox.showinfo(
                        "Save Configuration",
                        "Saved file at location:\n\n{}".format(
                            self.cfg_file_name.get()),
                    )

    def menu_selectall(self):
        """
        Add all elements in the Treeview to the selection.
        """
        for k in self.element_dict.keys():
            self.treeview.selection_add(k)

    def show_plugin_source_window(self):
        """
        Show the pop-up window to modify plugin sources
        """
        if not self.plugin_source_window:
            self.plugin_source_window = SourceWindow(master=self)
        else:
            self.plugin_source_window.toggle_show()

    # ---------------------------------------------------------------------- #
    #                         Run Analysis Methods
    # ---------------------------------------------------------------------- #
    def go_button_press(self):
        """
        Starts the analysis if all elements have been properly configured.
        This will run the analysis in a new thread and block out GUI editing 
        to prevent the analysis breaking.
        """
        (
            self.scorer,
            self.scorer_attrs,
            self.scorer_path,
        ) = self.scorer_widget.get_scorer_class_attrs_path()

        if self.scorer is None or self.scorer_attrs is None:
            tkinter.messagebox.showwarning("Incomplete Configuration",
                                           "No scoring plugin selected.")
        elif self.root_element is None:
            tkinter.messagebox.showwarning(
                "Incomplete Configuration",
                "No experimental design specified.")
        else:
            plugin, *_ = self.scorer_widget.get_selected_plugin()
            if plugin.md5_has_changed():
                proceed = askokcancel(
                    "Selected plugin has been modified.",
                    "The selected plugin has been modified on disk. Do you "
                    "want to proceed with the current version? To see changes "
                    "click 'Cancel' and refresh plugins before proceeding.",
                )
                if not proceed:
                    return
            if askyesno(
                    "Save Configuration?",
                    "Would you like to save the confiugration "
                    "file before proceeding?",
            ):
                self.menu_save()
            run = askyesno(
                "Begin Analysis?",
                "Click Yes when you are ready to start.\n\nThis could "
                "take some time so grab a cup of tea, or a beer if that's "
                "your thing, and enjoy the show.",
            )
            if run:
                self.configure_analysis()
                self.set_gui_state(tk.DISABLED)
                thread = threading.Thread(target=self.run_analysis)
                thread.setDaemon(True)
                self.analysis_thread = thread
                self.analysis_thread.start()
                self.after(100, self.poll_analysis_thread)

    def poll_logging_queue(self):
        """
        Polls the logging queue for messages to log.
        """
        try:
            log = get_logging_queue(init=True).get(0)
            log[CALLBACK](log[MESSAGE], **log[KWARGS])
            self.after(10, self.poll_logging_queue)
        except queue.Empty:
            self.after(10, self.poll_logging_queue)

    def poll_analysis_thread(self):
        """
        Polls the thread to check it's state. When it is finished, all stores
        are closed.
        """
        try:
            analysis_result = self.queue.get(0)
            self.handle_analysis_result(analysis_result)
        except queue.Empty:
            self.after(100, self.poll_analysis_thread)

    def handle_analysis_result(self, success):
        """
        Shows the appropriate messagebox and logs exceptions upon analysis
        completing.
        
        Parameters
        ----------
        success : `bool`
            Exception object if an error occured during analysis, otherwise
            None to indicate successful computation.
        """
        log_message(
            logging_callback=logging.info,
            msg="Closing stores...",
            extra={"oname": self.root_element.name},
        )
        self.root_element.store_close(children=True)
        log_message(
            logging_callback=logging.info,
            msg="Stores closed.",
            extra={"oname": self.root_element.name},
        )

        if success:
            showinfo("Analysis completed.",
                     "Analysis has completed successfully!")
            log_message(
                logging_callback=logging.info,
                msg="Completed successfully!",
                extra={"oname": self.root_element.name},
            )
        else:
            showwarning(
                "Error during analysis.",
                "An error occurred during the analysis. See log for details",
            )
            log_message(
                logging_callback=logging.info,
                msg="Completed, but with errors!",
                extra={"oname": self.root_element.name},
            )
        self.set_gui_state(tk.NORMAL)

    def run_analysis(self):
        """
        Runs the storemanager compute method.
        """
        try:
            self.root_element.validate()
            self.root_element.store_open(children=True)
            self.root_element.calculate()
            if self.root_element.tsv_requested:
                self.root_element.write_tsv()
            self.queue.put(True, block=False)
        except Exception as exception:
            log_message(
                logging_callback=logging.exception,
                msg=exception,
                extra={"oname": self.root_element.name},
            )
            self.queue.put(False, block=False)
        finally:
            return

    def configure_analysis(self):
        """
        Configures the attributes of the root_element by querying the GUI
        options.
        """
        try:
            self.root_element.force_recalculate = self.force_recalculate.get()
            self.root_element.component_outliers = self.component_outliers.get(
            )
            self.root_element.tsv_requested = self.tsv_requested.get()

            scorer_class = self.get_selected_scorer_class()
            scorer_class_attrs = self.get_selected_scorer_attrs()
            scorer_path = self.get_selected_scorer_path()
            self.root_element.scorer_class = scorer_class
            self.root_element.scorer_class_attrs = scorer_class_attrs
            self.root_element.scorer_path = scorer_path
        except Exception as e:
            log_message(
                logging_callback=logging.info,
                msg="An error occurred when trying to configure the "
                "root element.",
                extra={"oname": self.root_element.name},
            )
            log_message(
                logging_callback=logging.exception,
                msg=e,
                extra={"oname": self.root_element.name},
            )

    # ---------------------------------------------------------------------- #
    #                         GUI Modifications
    # ---------------------------------------------------------------------- #
    def set_gui_state(self, state):
        """
        Sets the state of the `go_button`, `treeview` and `treeview_buttons`.

        Parameters
        ----------
        state : `str`
            State to set, usually ``'normal'`` or ``'disabled'``

        """
        for btn in self.treeview_buttons:
            btn.config(state=state)
        self.go_button.config(state=state)
        if state == "normal":
            self.treeview.bind("<Button-2>", self.treeview_context_menu)
        else:
            self.treeview.bind("<Button-2>", lambda event: event)

    def refresh_plugins(self):
        """
        Refresh the plugins by re-checking the sources file.
        """
        if self.plugin_source_window:
            sources = self.plugin_source_window.sources
            self.scorer_widget.refresh_sources(sources)
Exemple #22
0
class Search:
    def __init__(self):
        self.window = Tk()
        self.window.title(
            "Search | All Record | National Textile University Faisalabad")
        self.window.iconbitmap('blood1.ico')
        can = Canvas(self.window, width=800, height=400, bg="white")
        can.pack(expand=YES, fill=BOTH)

        width = self.window.winfo_screenwidth()
        height = self.window.winfo_screenheight()
        # print("Width:",width,"\n","Height:",height)

        x = int(width / 2 - 800 / 2)
        y = int(height / 2 - 400 / 2)
        str1 = "980x450+" + str(x) + "+" + str(y)

        self.window.geometry(str1)
        self.window.maxsize(980, 450)
        self.window.minsize(980, 450)

    def add_fram_search(self):
        self.frame = Frame(self.window, width=850, height=385, bg="#ef5151")
        self.frame.place(x=77, y=20)

        self.l1 = Label(self.frame,
                        text="Enter Reg_N/Blood_G:",
                        font="Times 16 bold")
        self.l1.place(x=50, y=43)

        self.Entry_reg = Entry(self.frame, font="courior 14 bold")
        self.Entry_reg.place(x=280, y=43, height=30)

        # search-Button
        self.b1 = Button(self.frame, text="Search-RN", font="Times 12 bold")
        self.b1.place(x=510, y=40, height=37)
        self.b1.bind('<Button-1>', self.regno)

        self.b1 = Button(self.frame, text="Search-BG", font="Times 12 bold")
        self.b1.place(x=599, y=40, height=37)
        self.b1.bind('<Button-1>', self.bg)

        # Back-Buton
        self.b1 = Button(self.frame, text="Back", font="Times 12 bold")
        self.b1.place(x=690, y=40, height=37)
        self.b1.bind('<Button-1>', self.back)

        # for Styling Table
        style = Style()
        style.configure("mystyle.Treeview",
                        highlightthickness=0,
                        bd=0,
                        font=('Calibri 11'))  # Modify the font of the body
        style.configure(
            "mystyle.Treeview.Heading",
            font=('Calibri 13 bold'))  # Modify the font of the headings
        style.layout("mystyle.Treeview", [('mystyle.Treeview.treearea', {
            'sticky': 'nswe'
        })])  # Remove the borders

        # import TreeViewe
        self.tr = Treeview(self.frame,
                           columns=('A', 'B', 'C', 'D', 'E', 'F'),
                           selectmode="extended",
                           style="mystyle.Treeview")
        # heading key+text

        self.tr.heading("#0", text="Sr_No")
        self.tr.column("#0", minwidth=0, width=100, stretch=NO)

        self.tr.heading("#1", text="Name")
        self.tr.column("#1", minwidth=0, width=100, stretch=NO)

        self.tr.heading("#2", text="Reg_No")
        self.tr.column("#2", minwidth=0, width=100, stretch=NO)

        self.tr.heading("#3", text="Blood_Group")
        self.tr.column("#3", minwidth=0, width=100, stretch=NO)

        self.tr.heading("#4", text="Phone_No")
        self.tr.column("#4", minwidth=0, width=100, stretch=NO)

        self.tr.heading("#5", text="update")
        self.tr.column("#5", minwidth=0, width=100, stretch=NO)

        self.tr.heading("#6", text="delete")
        self.tr.column("#6", minwidth=0, width=100, stretch=NO)

        self.sb = Scrollbar(self.tr)
        self.sb.place(x=673, y=2, height=223, width=20, bordermode=OUTSIDE)
        self.sb.config(command=self.tr.yview)
        self.tr.config(yscrollcommand=self.sb.set)

        self.tr.place(x=50, y=100, width=691)
        # Remove All ROW
        self.Entry_reg.bind('<KeyRelease>', self.remove)

        self.tr.bind('<Double-Button-1>', self.action)

        self.window.mainloop()

    def regno(self, event):
        try:
            data = (self.Entry_reg.get(), )
            if self.Entry_reg.get() == "":
                msg.showwarning("Message!", "insert Reg No!")
            else:
                j = 1
                D = Database_Insert.search_details(data)
                if D:
                    self.Entry_reg.delete(0, END)
                    for i in D:
                        self.tr.insert('',
                                       index=j,
                                       text=j,
                                       values=(i[0], i[1], i[2], i[3],
                                               "update", "delete"))
                        j += 1
                else:
                    msg.showwarning("Message!", "No result Found!")

        except:
            msg.showwarning("Error!", "ERORR!")

    def bg(self, event):
        try:
            data = (self.Entry_reg.get(), )
            if self.Entry_reg.get() == "":
                msg.showwarning("Message!", "insert Blood_Group!")
            else:
                j = 1
                D = Database_Insert.search_details_bg(data)
                if D:
                    self.Entry_reg.delete(0, END)
                    for i in D:
                        self.tr.insert('',
                                       index=j,
                                       text=j,
                                       values=(i[0], i[1], i[2], i[3],
                                               "update", "delete"))
                        j += 1
                else:
                    msg.showwarning("Message!", "No result Found!")

        except:
            msg.showwarning("Error!", "ERORR!")

    def remove(self, event):
        x = self.tr.get_children()
        if x != '()':
            for child in x:
                self.tr.delete(child)

    def action(self, event):
        fcs = self.tr.focus()
        col = self.tr.identify_column(event.x)
        x = self.tr.item(fcs).get('values')
        text = x[1]
        data = (text, )

        if col == "#6":
            res = msg.askyesno("Message!", "Do you want to delete?")
            if res:
                d = Database_Insert.delete_details(data)
                if d:
                    msg.showinfo("Deleted", "Successfully")
                    self.window.destroy()
                    x = Search()
                    x.add_fram_search()
                else:
                    self.window.destroy()
                    x = Search()
                    x.add_fram_search()
        elif col == "#5":
            # self.window.destroy()
            x = Home.data(self.tr.item(fcs))
            x.add_frame()

    def back(self, event):
        self.window.destroy()
        x = Home.data()
        x.add_frame()
class TestcaseSelector:

    def start(self):

        # Create TK window
        self.root = Tk()

        # Create Style object for TK window
        self.root.style = Style()
        # Set default frame size to 800x640
        self.root.geometry('800x640')
        # Set Treeview row height to 40 so there's no overlap
        self.root.style.configure('Treeview',rowheight=40)

        # Set title and window size
        self.root.wm_title("Select Testcases to Run")

        # Create a frame for the treeview
        self.testcase_frame = Frame(self.root)

        # Create scrollbar for treeview
        scrollbar = Scrollbar(self.root)
        scrollbar.pack(side=RIGHT,fill=Y)

        # Create Treeview
        self.treeView = Treeview(self.testcase_frame)
        self.treeView.pack(expand=1,fill=BOTH)

        # Attach scrollbar to Treeview
        self.treeView.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.treeView.yview)

        # Get testcase name dictionary to use for filling out treeview
        testcase_dictionary = get_testcase_name_dictonary()
        self.testcase_data = {}
        self.testcase_run_data = {}

        for key in testcase_dictionary.keys():
            subsection = testcase_dictionary[key]

            self.testcase_data[key] = subsection

            s_p = self.treeView.insert('', END, text=key)

            for test in subsection:
                testcase_name = test._testMethodName
                testcase_name = testcase_name
                self.treeView.insert(s_p, END, text=testcase_name)

                self.testcase_run_data[testcase_name] = test

        self.webData = self.testcase_run_data

        # Create buttons for cancel and run tests
        run_button = Button(self.testcase_frame, text="Run", fg="green",command=self._save_selection,width=25,height=5)
        run_button.pack(side=LEFT,expand=1,fill=BOTH)
        quit_button = Button(self.testcase_frame, text="Cancel", fg="red", command=self.treeView.quit,width=25,height=5)
        quit_button.pack(side=RIGHT,expand=1,fill=BOTH)

        # Pack the rest of the frame and tell it to scale on both x and y axis
        self.testcase_frame.pack(expand=1,fill=BOTH)

    def get_tests_from_selected_names(self,names):
        ret_tests = {}
        for name in names:
            ret_tests[name] = self.webData[name]

        return ret_tests

    def _save_selection(self):
        selected_tests = self.treeView.selection()

        output=[]
        for selection in selected_tests:
            item_text = self.treeView.item(selection,'text')
            if 'test_' in item_text:
                if item_text not in output:
                    output.append(item_text)
                else:
                    pass
            elif 'Tests' in item_text:
                for test in self.testcase_data[item_text]:
                    output.append(test._testMethodName)
                # output = output + self.testSectionData[item_text]

        self.testcases = self.get_tests_from_selected_names(output)
        self.root.quit()

    def get_testcases(self):
        self.start()
        self.root.mainloop()
        self.root.destroy()

        # Try/Except to fail gracefully
        try:
            return self.testcases
        except:
            exit(0)
Exemple #24
0
class XRDApp(Toplevel):
    def __init__(self, *args, **kwargs):

        Toplevel.__init__(self, *args, **kwargs)
        Toplevel.wm_title(self, "XRDApp")
        Toplevel.config(self, background="white")
        self.wm_geometry("650x650")
        center(self)
        self.initUI()

    def initUI(self):
        global refsamplenameslist, Patternsamplenameslist

        self.master.withdraw()
        self.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.canvas0 = tk.Canvas(self, borderwidth=0, background="#ffffff")
        self.superframe = Frame(self.canvas0, background="#ffffff")
        self.canvas0.pack(side="left", fill="both", expand=True)

        label = tk.Label(self.canvas0,
                         text="XRD DATA Analyzer",
                         font=LARGE_FONT,
                         bg="black",
                         fg="white")
        label.pack(fill=tk.X, expand=0)

        frame1 = Frame(self.canvas0, borderwidth=0, bg="white")
        frame1.pack(fill=tk.BOTH, expand=1)
        frame1.bind("<Configure>", self.onFrameConfigure)
        self.fig1 = plt.figure(figsize=(1, 3))
        canvas = FigureCanvasTkAgg(self.fig1, frame1)
        canvas.get_tk_widget().pack(fill=tk.BOTH, expand=1)
        self.XRDgraph = plt.subplot2grid((1, 1), (0, 0), colspan=3)
        self.toolbar = NavigationToolbar2Tk(canvas, frame1)
        self.toolbar.update()
        canvas._tkcanvas.pack(fill=tk.BOTH, expand=1)

        frame2 = Frame(self.canvas0, borderwidth=0, bg="white")
        frame2.pack(fill=tk.BOTH, expand=0)

        frame21 = Frame(frame2, borderwidth=0, bg="lightgrey")
        frame21.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        frame211 = Frame(frame21, borderwidth=0, bg="lightgrey")
        frame211.pack(fill=tk.BOTH, expand=1)
        self.shift = tk.DoubleVar()
        Entry(frame211, textvariable=self.shift, width=3).pack(side=tk.LEFT,
                                                               fill=tk.X,
                                                               expand=1)
        self.shiftBut = Button(frame211, text="X Shift",
                               command=self.shiftX).pack(side=tk.LEFT,
                                                         expand=1)
        self.shift.set(0)
        self.shiftYval = tk.DoubleVar()
        Entry(frame211, textvariable=self.shiftYval,
              width=3).pack(side=tk.LEFT, fill=tk.X, expand=1)
        self.shiftYBut = Button(frame211, text="Y Shift",
                                command=self.shiftY).pack(side=tk.LEFT,
                                                          expand=1)
        self.shiftYval.set(0)
        self.CheckBkgRemoval = Button(frame211,
                                      text="BkgRemoval",
                                      command=self.backgroundremoval).pack(
                                          side=tk.LEFT, expand=1)

        #        frame212=Frame(frame21,borderwidth=0,  bg="lightgrey")
        #        frame212.pack(fill=tk.BOTH,expand=1)
        #        refpattern=StringVar()
        #        refpatternlist=['Original','Si','ITO']#to be replace by actual files in a specific folder
        #        cbbox = ttk.Combobox(frame212, textvariable=refpattern, values=refpatternlist)
        #        cbbox.pack(side=tk.LEFT,expand=0)
        #        refpattern.set(refpatternlist[0])
        #        self.refbut = Button(frame212, text="ShiftToRef",command = self.shifttoRef).pack(side=tk.LEFT,expand=1)

        frame213 = Frame(frame21, borderwidth=0, bg="lightgrey")
        frame213.pack(fill=tk.BOTH, expand=1)
        self.rescale = tk.DoubleVar()
        Entry(frame213, textvariable=self.rescale, width=3).pack(side=tk.LEFT,
                                                                 fill=tk.X,
                                                                 expand=1)
        self.rescale.set(1000)
        self.rescaleBut = Button(frame213,
                                 text="Rescale to ref",
                                 command=self.scaleYtoRef).pack(side=tk.LEFT,
                                                                expand=1)
        self.backtoOriginalBut = Button(frame213,
                                        text="BackToOriginal",
                                        command=self.backtoOriginal).pack(
                                            side=tk.LEFT, expand=1)

        frame22 = Frame(frame2, borderwidth=0, bg="white")
        frame22.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        frame221 = Frame(frame22, borderwidth=0, bg="white")
        frame221.pack(fill=tk.BOTH, expand=1)
        self.importBut = Button(frame221,
                                text="Import",
                                command=self.importDATA).pack(side=tk.LEFT,
                                                              expand=1)
        self.importRefBut = Button(frame221,
                                   text="ImportRef",
                                   command=self.importRefDATA).pack(
                                       side=tk.LEFT, expand=1)
        self.UpdateBut = Button(frame221,
                                text="Update",
                                command=lambda: self.updateXRDgraph(0)).pack(
                                    side=tk.LEFT, expand=1)
        frame222 = Frame(frame22, borderwidth=0, bg="grey")
        frame222.pack(fill=tk.BOTH, expand=1)
        self.ShowPeakDetectionBut = Button(frame222,
                                           text="Peak Detection",
                                           command=self.PeakDetection).pack(
                                               side="left", expand=1)
        self.ChangePeakNameBut = Button(frame222,
                                        text="Change Peak Names",
                                        command=self.ChangePeakNames).pack(
                                            side="left", expand=1)
        self.CheckPeakNames = IntVar()
        Checkbutton(frame222,
                    text="ShowNames",
                    variable=self.CheckPeakNames,
                    onvalue=1,
                    offvalue=0,
                    height=1,
                    width=10,
                    command=lambda: self.updateXRDgraph(0),
                    fg='black',
                    background='grey').pack(side=tk.LEFT, expand=1)
        frame223 = Frame(frame22, borderwidth=0, bg="grey")
        frame223.pack(fill=tk.BOTH, expand=1)
        self.thresholdPeakDet = tk.DoubleVar()
        Entry(frame223, textvariable=self.thresholdPeakDet,
              width=5).pack(side=tk.LEFT, expand=1)
        self.thresholdPeakDet.set(0.05)
        tk.Label(frame223, text="Threshold", bg="grey").pack(side=tk.LEFT,
                                                             expand=1)
        self.MinDistPeakDet = tk.DoubleVar()
        Entry(frame223, textvariable=self.MinDistPeakDet,
              width=3).pack(side=tk.LEFT, expand=1)
        self.MinDistPeakDet.set(40)
        tk.Label(frame223, text="MinDist", bg="grey").pack(side=tk.LEFT,
                                                           expand=1)
        self.CheckPeakDetec = IntVar()
        Checkbutton(frame223,
                    text="Show",
                    variable=self.CheckPeakDetec,
                    onvalue=1,
                    offvalue=0,
                    height=1,
                    width=3,
                    command=lambda: self.updateXRDgraph(0),
                    fg='black',
                    background='grey').pack(side=tk.LEFT, expand=1)

        #        frame23=Frame(frame2,borderwidth=0,  bg="lightgrey")
        #        frame23.pack(fill=tk.BOTH,expand=1)
        #        frame231=Frame(frame23,borderwidth=0,  bg="lightgrey")
        #        frame231.pack(fill=tk.BOTH,expand=1)
        self.ExportBut = Button(frame221, text="Export",
                                command=self.Export).pack(side="left",
                                                          expand=1)
        self.ExportRefFileBut = Button(frame221,
                                       text="ExportasRefFile",
                                       command=self.ExportasRef).pack(
                                           side="left", expand=1)
        #        self.GraphCheck = IntVar()
        #        legend=Checkbutton(frame23,text='Graph',variable=self.GraphCheck,
        #                           onvalue=1,offvalue=0,height=1, width=10, command = (), bg="lightgrey")
        #        legend.pack(expand=1)
        #        self.PeakData = IntVar()
        #        legend=Checkbutton(frame23,text='PeakData',variable=self.PeakData,
        #                           onvalue=1,offvalue=0,height=1, width=10, command = (), bg="lightgrey")
        #        legend.pack(expand=1)

        frame5 = Frame(self.canvas0, borderwidth=0, bg="white")
        frame5.pack(fill=tk.BOTH, expand=1)
        frame3 = Frame(frame5, borderwidth=0, bg="white")
        frame3.pack(side="left", fill=tk.BOTH, expand=1)
        frame32 = Frame(frame3, borderwidth=0, bg="white")
        frame32.pack(fill=tk.BOTH, expand=1)

        #listbox for imported samples
        self.frame322 = Frame(frame32, borderwidth=0, bg="white")
        self.frame322.pack(fill=tk.BOTH, expand=1)
        self.frame3221 = Frame(self.frame322, borderwidth=0, bg="white")
        self.frame3221.pack(fill=tk.BOTH, expand=1)
        importedsamplenames = StringVar()
        self.listboxsamples = Listbox(self.frame3221,
                                      listvariable=importedsamplenames,
                                      selectmode=tk.MULTIPLE,
                                      width=15,
                                      height=3,
                                      exportselection=0)
        self.listboxsamples.bind('<<ListboxSelect>>', self.updateXRDgraph)
        self.listboxsamples.pack(side="left", fill=tk.BOTH, expand=1)
        scrollbar = tk.Scrollbar(self.frame3221, orient="vertical")
        scrollbar.config(command=self.listboxsamples.yview)
        scrollbar.pack(side="right", fill="y")
        self.listboxsamples.config(yscrollcommand=scrollbar.set)

        for item in Patternsamplenameslist:
            self.listboxsamples.insert(tk.END, item)

        #lisbox for ref pattern
        self.frame323 = Frame(frame32, borderwidth=0, bg="white")
        self.frame323.pack(fill=tk.BOTH, expand=1)
        self.frame3231 = Frame(self.frame323, borderwidth=0, bg="white")
        self.frame3231.pack(fill=tk.BOTH, expand=1)
        refsamplenames = StringVar()
        self.listboxref = Listbox(self.frame3231,
                                  listvariable=refsamplenames,
                                  selectmode=tk.MULTIPLE,
                                  width=15,
                                  height=3,
                                  exportselection=0)
        self.listboxref.bind('<<ListboxSelect>>', self.updateXRDgraph)
        self.listboxref.pack(side="left", fill=tk.BOTH, expand=1)
        scrollbar = tk.Scrollbar(self.frame3231, orient="vertical")
        scrollbar.config(command=self.listboxref.yview)
        scrollbar.pack(side="right", fill="y")
        self.listboxref.config(yscrollcommand=scrollbar.set)

        for item in refsamplenameslist:
            self.listboxref.insert(tk.END, item)

#        frame321=Frame(frame32,borderwidth=0,  bg="white")
#        frame321.pack(fill=tk.X,expand=0)
#        self.addtolistBut = Button(frame321, text="Add to list",command = ()).pack(side=tk.LEFT,expand=1)
#        self.RemoveFromListBut = Button(frame321, text="Remove from list",command = ()).pack(side=tk.LEFT,expand=1)

        self.frame4 = Frame(frame5, borderwidth=0, bg="white")
        self.frame4.pack(side="right", fill=tk.BOTH, expand=1)
        self.frame41 = Frame(self.frame4, borderwidth=0, bg="white")
        self.frame41.pack(side="right", fill=tk.BOTH, expand=1)

        #        self.addtolistBut = Button(self.frame4, text="Add to list",command = ()).pack(side=tk.LEFT,expand=1)
        #        self.TableBuilder(self.frame4)
        self.CreateTable()

#%%#############

    def on_closing(self):
        global DATA, RefPattDATA, Patternsamplenameslist, colorstylelist

        if messagebox.askokcancel("Quit", "Do you want to quit?"):
            DATA = {}
            RefPattDATA = {}
            Patternsamplenameslist = []
            colorstylelist = [
                'black', 'red', 'blue', 'brown', 'green', 'cyan', 'magenta',
                'olive', 'navy', 'orange', 'gray', 'aliceblue', 'antiquewhite',
                'aqua', 'aquamarine', 'azure', 'beige', 'bisque',
                'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood',
                'cadetblue', 'chartreuse', 'chocolate', 'coral',
                'cornflowerblue', 'cornsilk', 'crimson', 'darkblue',
                'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen',
                'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange',
                'darkorchid', 'darkred', 'darksalmon', 'darkseagreen',
                'darkslateblue', 'darkslategray', 'darkturquoise',
                'darkviolet', 'deeppink', 'deepskyblue', 'dimgray',
                'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen',
                'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod',
                'greenyellow', 'honeydew', 'hotpink', 'indianred', 'indigo',
                'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen',
                'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan',
                'lightgoldenrodyellow', 'lightgreen', 'lightgray', 'lightpink',
                'lightsalmon', 'lightseagreen', 'lightskyblue',
                'lightslategray', 'lightsteelblue', 'lightyellow', 'lime',
                'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine',
                'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen',
                'mediumslateblue', 'mediumspringgreen', 'mediumturquoise',
                'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose',
                'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive',
                'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod',
                'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip',
                'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple',
                'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon',
                'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver',
                'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen',
                'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise',
                'violet', 'wheat', 'white', 'whitesmoke', 'yellow',
                'yellowgreen'
            ]
            plt.close()
            self.destroy()
            self.master.deiconify()

    def onFrameConfigure(self, event):
        #self.canvas0.configure(scrollregion=self.canvas0.bbox("all"))
        self.canvas0.configure(scrollregion=(0, 0, 500, 500))

#%%

    def updateXRDgraph(self, a):
        global DATA, RefPattDATA, colorstylelist, samplestakenforplot

        self.XRDgraph.clear()

        coloridx = 0
        #plot patterns from DATA
        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            minX = min(DATA[samplestakenforplot[0]][2])
            maxX = max(DATA[samplestakenforplot[0]][2])
            minY = min(DATA[samplestakenforplot[0]][3])
            maxY = max(DATA[samplestakenforplot[0]][3])
            for item in samplestakenforplot:
                x = DATA[item][2]
                y = DATA[item][3]
                if min(x) < minX:
                    minX = min(x)
                if max(x) > maxX:
                    maxX = max(x)
                if min(y) < minY:
                    minY = min(y)
                if max(y) > maxY:
                    maxY = max(y)

                self.XRDgraph.plot(x,
                                   y,
                                   color=colorstylelist[coloridx],
                                   label=item)
                coloridx += 1

            #add text for Peak Names
            if self.CheckPeakNames.get():
                for item in range(len(peaknamesforplot)):
                    plt.text(peaknamesforplot[item][0],
                             peaknamesforplot[item][1],
                             peaknamesforplot[item][2],
                             rotation=90,
                             verticalalignment='bottom',
                             horizontalalignment='left',
                             multialignment='center')

        #plot from RefPattDATA
        reftakenforplot = [
            self.listboxref.get(idx) for idx in self.listboxref.curselection()
        ]
        for item in reftakenforplot:
            x = RefPattDATA[item][0]
            y = RefPattDATA[item][1]

            lines = []
            for i in range(len(x)):
                pair = [(x[i], 0), (x[i], y[i])]
                lines.append(pair)

            linecoll = matcoll.LineCollection(lines,
                                              color='black',
                                              linestyle='dashed')
            #            linecoll = matcoll.LineCollection(lines)
            self.XRDgraph.add_collection(linecoll)
            self.XRDgraph.scatter(x,
                                  y,
                                  label=item,
                                  color=colorstylelist[coloridx])
            coloridx += 1

            if self.CheckPeakNames.get():
                for item1 in range(len(RefPattDATA[item][0])):
                    if samplestakenforplot != []:
                        if RefPattDATA[item][0][item1] > minX and RefPattDATA[
                                item][0][item1] < maxX:
                            plt.text(RefPattDATA[item][0][item1],
                                     RefPattDATA[item][1][item1],
                                     RefPattDATA[item][2][item1],
                                     rotation=90,
                                     verticalalignment='bottom',
                                     horizontalalignment='left',
                                     multialignment='center')
                    else:
                        plt.text(RefPattDATA[item][0][item1],
                                 RefPattDATA[item][1][item1],
                                 RefPattDATA[item][2][item1],
                                 rotation=90,
                                 verticalalignment='bottom',
                                 horizontalalignment='left',
                                 multialignment='center')

        coloridx += 1

        if self.CheckPeakDetec.get():
            if samplestakenforplot != []:
                for item in samplestakenforplot:
                    for item1 in range(len(DATA[item][5])):
                        self.XRDgraph.plot(DATA[item][5][item1][0],
                                           DATA[item][5][item1][1],
                                           color=colorstylelist[coloridx])
                    for item1 in range(len(DATA[item][6])):
                        self.XRDgraph.plot(
                            [DATA[item][6][item1][0], DATA[item][6][item1][1]],
                            [DATA[item][6][item1][2], DATA[item][6][item1][3]],
                            color=colorstylelist[coloridx + 1])
                    for item1 in range(len(DATA[item][7])):
                        self.XRDgraph.plot(
                            [DATA[item][7][item1][0], DATA[item][7][item1][1]],
                            [DATA[item][7][item1][2], DATA[item][7][item1][3]],
                            color=colorstylelist[coloridx + 1])

        #legends and graph styles
        if samplestakenforplot != [] or reftakenforplot != []:
            self.XRDgraph.legend()
        self.XRDgraph.set_ylabel("Intensity (a.u.)")
        self.XRDgraph.set_xlabel("2\u0398 (degree)")
        if samplestakenforplot != []:
            self.XRDgraph.axis([minX, maxX, minY, 1.1 * maxY])
        plt.gcf().canvas.draw()
        self.CreateTable()

    class PopulateListofPeakNames(tk.Frame):
        def __init__(self, root):

            tk.Frame.__init__(self, root)
            self.canvas0 = tk.Canvas(root, borderwidth=0, background="#ffffff")
            self.frame = tk.Frame(self.canvas0, background="#ffffff")
            self.vsb = tk.Scrollbar(root,
                                    orient="vertical",
                                    command=self.canvas0.yview)
            self.canvas0.configure(yscrollcommand=self.vsb.set)

            self.vsb.pack(side="right", fill="y")
            self.canvas0.pack(side="left", fill="both", expand=True)
            self.canvas0.create_window((4, 4),
                                       window=self.frame,
                                       anchor="nw",
                                       tags="self.frame")

            self.frame.bind("<Configure>", self.onFrameConfigure)

            self.populate()

        def populate(self):
            global DATA, listofanswer, samplestakenforplot

            rowpos = 1
            if samplestakenforplot != []:
                for item in samplestakenforplot:
                    for item1 in range(len(DATA[item][4])):
                        label = tk.Label(self.frame,
                                         text=item,
                                         fg='black',
                                         background='white')
                        label.grid(row=rowpos, column=0, columnspan=1)
                        label = tk.Label(self.frame,
                                         text="%.2f" %
                                         DATA[item][4][item1]["Position"],
                                         fg='black',
                                         background='white')
                        label.grid(row=rowpos, column=1, columnspan=1)
                        textinit = tk.StringVar()
                        listofanswer[str(
                            DATA[item][4][item1]["Position"])] = Entry(
                                self.frame, textvariable=textinit)
                        listofanswer[str(
                            DATA[item][4][item1]["Position"])].grid(
                                row=rowpos, column=2, columnspan=2)
                        textinit.set(DATA[item][4][item1]["PeakName"])

                        rowpos = rowpos + 1

        def onFrameConfigure(self, event):
            '''Reset the scroll region to encompass the inner frame'''
            self.canvas0.configure(scrollregion=self.canvas0.bbox("all"))

    def ChangePeakNames(self):
        global DATA

        self.window = tk.Toplevel()
        self.window.wm_title("Change Peak Names")
        center(self.window)
        self.window.geometry("400x300")

        Button(self.window, text="Update", command=self.UpdatePeakNames).pack()

        self.PopulateListofPeakNames(self.window).pack(side="top",
                                                       fill="both",
                                                       expand=True)

    def UpdatePeakNames(self):
        global DATA, listofanswer, samplestakenforplot, peaknamesforplot

        peaknamesforplot = []

        for item in samplestakenforplot:
            for item1 in range(len(DATA[item][4])):
                DATA[item][4][item1]["PeakName"] = listofanswer[str(
                    DATA[item][4][item1]["Position"])].get()
                peaknamesforplot.append([
                    DATA[item][4][item1]["Position"],
                    DATA[item][4][item1]["Intensity"],
                    DATA[item][4][item1]["PeakName"]
                ])

        self.window.destroy()
        self.updateXRDgraph(0)

#%%

    def backgroundremoval(self):
        global DATA

        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for item in samplestakenforplot:
                y = DATA[item][3]
                y = np.array(y)
                base = peakutils.baseline(y, 3)
                DATA[item][3] = list(y - base)

        self.updateXRDgraph(0)

    def shiftX(self):
        global DATA

        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for item in samplestakenforplot:
                x = DATA[item][2]
                DATA[item][2] = [item1 + self.shift.get() for item1 in x]

        self.updateXRDgraph(0)

    def shiftY(self):
        global DATA
        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for item in samplestakenforplot:
                print(self.shiftYval.get())
                y = DATA[item][3]
                DATA[item][3] = [item1 + self.shiftYval.get() for item1 in y]

        self.updateXRDgraph(0)

    def shifttoRef(self):
        global DATA
        #        still to be done
        #        automatic detection of peaks and comparison to the selected RefPattern
        #        then shifts the data to match the ref peak

        self.updateXRDgraph(0)

    def scaleYtoRef(self):
        global DATA

        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for item in samplestakenforplot:
                y = DATA[item][3]
                maxy = max(y)
                miny = min(y)
                DATA[item][3] = [
                    ((item1 - miny) / (maxy - miny)) * self.rescale.get()
                    for item1 in y
                ]

        self.updateXRDgraph(0)

    def backtoOriginal(self):
        global DATA

        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for item in samplestakenforplot:
                DATA[item][2] = DATA[item][0]
                DATA[item][3] = DATA[item][1]

        self.updateXRDgraph(0)

#%%

    def PeakDetection(self):
        global DATA, peaknamesforplot
        peaknamesforplot = []
        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:

            for item in samplestakenforplot:
                #reinitialize list of dict
                DATA[item][4] = []  #list of dictionaries
                DATA[item][5] = []  #list of points taken for the peak analysis
                DATA[item][6] = []  #baselines
                DATA[item][7] = []  #FWHM lines
                x = np.array(DATA[item][2])
                y = np.array(DATA[item][3])
                #get peak position
                indexes = peakutils.indexes(y,
                                            thres=self.thresholdPeakDet.get(),
                                            min_dist=self.MinDistPeakDet.get())

                for item1 in range(len(indexes)):
                    tempdat = {}
                    nbofpoints = 80  #on each side of max position
                    appendcheck = 0
                    while (1):
                        try:
                            x0 = x[indexes[item1] - nbofpoints:indexes[item1] +
                                   nbofpoints]
                            y0 = y[indexes[item1] - nbofpoints:indexes[item1] +
                                   nbofpoints]

                            #baseline height
                            bhleft = np.mean(y0[:20])
                            bhright = np.mean(y0[-20:])
                            baselineheightatmaxpeak = (bhleft + bhright) / 2

                            if abs(bhleft - bhright
                                   ) < 50:  #arbitrary choice of criteria...
                                #find FWHM
                                d = y0 - ((max(y0) - bhright) / 2)
                                ind = np.where(d > bhright)[0]

                                hl = (x0[ind[0] - 1] * y0[ind[0]] -
                                      y0[ind[0] - 1] * x0[ind[0]]) / (
                                          x0[ind[0] - 1] - x0[ind[0]])
                                ml = (y0[ind[0] - 1] - hl) / x0[ind[0] - 1]
                                yfwhm = ((max(y0) - baselineheightatmaxpeak) /
                                         2) + baselineheightatmaxpeak
                                xleftfwhm = (yfwhm - hl) / ml
                                hr = (x0[ind[-1]] * y0[ind[-1] + 1] -
                                      y0[ind[-1]] * x0[ind[-1] + 1]) / (
                                          x0[ind[-1]] - x0[ind[-1] + 1])
                                mr = (y0[ind[-1]] - hr) / x0[ind[-1]]
                                xrightfwhm = (yfwhm - hr) / mr

                                FWHM = abs(xrightfwhm - xleftfwhm)
                                Peakheight = max(y0) - baselineheightatmaxpeak
                                center = x[indexes[item1]]

                                tempdat["Position"] = center
                                tempdat["FWHM"] = FWHM
                                tempdat["Intensity"] = Peakheight
                                tempdat["PeakName"] = ''

                                DATA[item][5].append([x0, y0])
                                DATA[item][6].append(
                                    [x0[0], x0[-1], bhleft, bhright])
                                DATA[item][7].append(
                                    [xleftfwhm, xrightfwhm, yfwhm, yfwhm])

                                appendcheck = 1
                                break
                            else:
                                if nbofpoints >= 15:
                                    nbofpoints -= 10
                                else:
                                    print("indexerror unsolvable")
                                    break
                        except IndexError:
                            if nbofpoints >= 15:
                                nbofpoints -= 10
                            else:
                                print("indexerror unsolvable")
                                break
                    if appendcheck:
                        DATA[item][4].append(tempdat)

        for item in samplestakenforplot:
            for item1 in range(len(DATA[item][4])):
                peaknamesforplot.append([
                    DATA[item][4][item1]["Position"],
                    DATA[item][4][item1]["Intensity"],
                    DATA[item][4][item1]["PeakName"]
                ])

        self.CreateTable()
        self.updateXRDgraph(0)

#%%

    def importRefDATA(self):
        global DATA, RefPattDATA, refsamplenameslist

        #ask for the files
        file_path = filedialog.askopenfilenames(
            title="Please select the reference XRD pattern")

        #read the files and fill the RefPattDATA dictionary
        for filename in file_path:
            filetoread = open(filename, "r")
            filerawdata = filetoread.readlines()
            samplename = os.path.splitext(os.path.basename(filename))[0]
            refsamplenameslist.append(samplename)

            RefPattDATA[samplename] = [[], [], []]
            for row in filerawdata:
                RefPattDATA[samplename][0].append(float(row.split("\t")[0]))
                RefPattDATA[samplename][1].append(float(row.split("\t")[1]))
                try:
                    RefPattDATA[samplename][2].append(
                        str(row.split("\t")[2])[:-1])
                except:
                    RefPattDATA[samplename][2].append("")

        #update the listbox
        self.frame3231.destroy()
        self.frame3231 = Frame(self.frame323, borderwidth=0, bg="white")
        self.frame3231.pack(fill=tk.BOTH, expand=1)
        refsamplenames = StringVar()
        self.listboxref = Listbox(self.frame3231,
                                  listvariable=refsamplenames,
                                  selectmode=tk.MULTIPLE,
                                  width=15,
                                  height=3,
                                  exportselection=0)
        self.listboxref.bind('<<ListboxSelect>>', self.updateXRDgraph)
        self.listboxref.pack(side="left", fill=tk.BOTH, expand=1)
        scrollbar = tk.Scrollbar(self.frame3231, orient="vertical")
        scrollbar.config(command=self.listboxref.yview)
        scrollbar.pack(side="right", fill="y")
        self.listboxref.config(yscrollcommand=scrollbar.set)

        for item in refsamplenameslist:
            self.listboxref.insert(tk.END, item)

    def importDATA(self):
        global DATA, Patternsamplenameslist

        #ask for the files
        file_path = filedialog.askopenfilenames(
            title="Please select the XRD files")
        #self.WhichXRD()
        DataSource = messagebox.askquestion(
            title='Data Source',
            message=
            'Which XRD machine gave you your precious data? \n yes = EPFL, no = CSEM'
        )

        #read the files and fill the DATA dictionary
        for filename in file_path:
            tempdat = []
            filetoread = open(filename, "r")
            samplename = os.path.splitext(os.path.basename(filename))[0]
            filerawdata = filetoread.readlines()

            x = []
            y = []

            if DataSource == "yes":
                for item in filerawdata:
                    x.append(float(item.split(' ')[0]))
                    y.append(float(item.split(' ')[1]))
            elif DataSource == "no":
                for line in filerawdata[30:]:
                    x.append(float(line.split(',')[0]))
                    y.append(float(line.split(',')[1]))

            tempdat.append(x)  #original x data
            tempdat.append(y)  #original y data
            tempdat.append(
                x)  #corrected x, set as the original on first importation
            tempdat.append(
                y)  #corrected y, set as the original on first importation
            tempdat.append([])  #4 peak data, list of dictionaries
            tempdat.append([])  #5
            tempdat.append([])  #6
            tempdat.append([])  #7

            DATA[samplename] = tempdat
            Patternsamplenameslist.append(samplename)

        #update the listbox
        self.frame3221.destroy()
        self.frame3221 = Frame(self.frame322, borderwidth=0, bg="white")
        self.frame3221.pack(fill=tk.BOTH, expand=1)
        importedsamplenames = StringVar()
        self.listboxsamples = Listbox(self.frame3221,
                                      listvariable=importedsamplenames,
                                      selectmode=tk.MULTIPLE,
                                      width=15,
                                      height=3,
                                      exportselection=0)
        self.listboxsamples.bind('<<ListboxSelect>>', self.updateXRDgraph)
        self.listboxsamples.pack(side="left", fill=tk.BOTH, expand=1)
        scrollbar = tk.Scrollbar(self.frame3221, orient="vertical")
        scrollbar.config(command=self.listboxsamples.yview)
        scrollbar.pack(side="right", fill="y")
        self.listboxsamples.config(yscrollcommand=scrollbar.set)

        for item in Patternsamplenameslist:
            self.listboxsamples.insert(tk.END, item)

#    def WhichXRD(self):
#        win = Toplevel()
#        win.title('Data Source')
#        message = 'Which XRD machine gave you your precious data?'
#        Label(Toplevel(), text='123').pack()
#        Button(win, text='EPFL')
#        Button(win, text='CSEM')

#%%

    def Export(self):
        global DATA

        f = filedialog.asksaveasfilename(defaultextension=".png",
                                         filetypes=(("graph file", "*.png"),
                                                    ("All Files", "*.*")))
        self.fig1.savefig(f, dpi=300)

        testdata = ['name\tPeakName\tPosition\tIntensity\tFWHM\n']
        dattotxt = []
        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for key in samplestakenforplot:
                for item in DATA[key][4]:
                    testdata.append(key + '\t' + item["PeakName"] + '\t' +
                                    str("%.2f" % item["Position"]) + '\t' +
                                    str("%.2f" % item["Intensity"]) + '\t' +
                                    str("%.2f" % item["FWHM"]) + '\n')
                x = ["2theta", "degree", ""]
                y = ["XRD intensity", "a.u.", key]
                for item in range(len(DATA[key][2])):
                    x.append(DATA[key][2][item])
                    y.append(DATA[key][3][item])
                dattotxt.append(x)
                dattotxt.append(y)

        file = open(f[:-4] + "PeakDat.txt", 'w')
        file.writelines("%s" % item for item in testdata)
        file.close()

        dattotxt = map(list, six.moves.zip_longest(*dattotxt, fillvalue=' '))
        dattotxt1 = []
        for item in dattotxt:
            line = ""
            for item1 in item:
                line = line + str(item1) + "\t"
            line = line[:-1] + "\n"
            dattotxt1.append(line)

        file = open(str(f[:-4] + "_dat.txt"), 'w')
        file.writelines("%s" % item for item in dattotxt1)
        file.close()

    def ExportasRef(self):
        global DATA, RefPattDATA

        f = filedialog.asksaveasfilename(defaultextension=".txt")
        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for key in samplestakenforplot:
                datforref = []
                for item in range(len(DATA[key][2])):
                    datforref.append(
                        str(DATA[key][2][item]) + '\t' +
                        str(DATA[key][3][item]) + '\n')
                file = open(str(f[:-4] + "_" + key + ".txt"), 'w')
                file.writelines("%s" % item for item in datforref)
                file.close()

#%%

    def CreateTable(self):
        global DATA
        global testdata
        testdata = []
        #self.parent.grid_rowconfigure(0,weight=1)
        #self.parent.grid_columnconfigure(0,weight=1)
        #        self.parent.config(background="white")

        self.frame41.destroy()
        self.frame41 = Frame(self.frame4, borderwidth=0, bg="white")
        self.frame41.pack(side="right", fill=tk.BOTH, expand=1)

        samplestakenforplot = [
            self.listboxsamples.get(idx)
            for idx in self.listboxsamples.curselection()
        ]
        if samplestakenforplot != []:
            for key in samplestakenforplot:
                for item in DATA[key][4]:
                    testdata.append([
                        key, item["PeakName"],
                        "%.2f" % item["Position"],
                        "%.2f" % item["Intensity"],
                        "%.2f" % item["FWHM"]
                    ])

        self.tableheaders = ('name', 'PeakName', 'Position', 'Intensity',
                             'FWHM')

        # Set the treeview
        self.tree = Treeview(self.frame41,
                             columns=self.tableheaders,
                             show="headings")

        for col in self.tableheaders:
            self.tree.heading(
                col,
                text=col.title(),
                command=lambda c=col: self.sortby(self.tree, c, 0))
            self.tree.column(
                col,
                width=int(round(1.1 * tkFont.Font().measure(col.title()))),
                anchor='n')

        scrollbar = tk.Scrollbar(self.frame41, orient="vertical")
        scrollbar.config(command=self.tree.yview)
        scrollbar.pack(side="right", fill="y")
        self.tree.config(yscrollcommand=scrollbar.set)
        self.tree.pack(side="left", fill=tk.BOTH, expand=1)

        self.treeview = self.tree

        self.insert_data(testdata)

    def insert_data(self, testdata):
        for item in testdata:
            self.treeview.insert('', 'end', values=item)

    def sortby(self, tree, col, descending):
        data = [(tree.set(child, col), child)
                for child in tree.get_children('')]
        try:
            data.sort(key=lambda t: float(t[0]), reverse=descending)
        except ValueError:
            data.sort(reverse=descending)
        for ix, item in enumerate(data):
            tree.move(item[1], '', ix)
        # switch the heading so it will sort in the opposite direction
        tree.heading(col,
                     text=col.capitalize(),
                     command=lambda _col_=col: self.sortby(
                         tree, _col_, int(not descending)))
Exemple #25
0
class StoreView(BaseView):

    ########
    # Initializes and places all GUI elements.
    def _create_widgets(self):
        # left frame
        self._leftFrame = Frame(self)
        self._imgLabel = Label(self._leftFrame)
        self._locLabel = Label(self._leftFrame,
                               text="Location:",
                               font=BaseView.NORMAL_FONT)
        self._locPreview = SimpleLocationView(self._leftFrame)

        # right frame
        self._rightFrame = Frame(self)
        self._nameLabel = Label(self._rightFrame,
                                compound=LEFT,
                                text="Name",
                                font=BaseView.LARGE_FONT)
        self._descLabel = Label(self._rightFrame,
                                text="Description:",
                                font=BaseView.NORMAL_FONT)
        self._descFrame = Frame(self._rightFrame)
        self._descText = Text(self._descFrame,
                              width=50,
                              height=4,
                              state=DISABLED,
                              wrap=WORD,
                              font=BaseView.NORMAL_FONT)
        self._descScroll = Scrollbar(self._descFrame,
                                     command=self._descText.yview)
        self._descText.config(yscrollcommand=self._descScroll.set)
        self._notesLabel = Label(self._rightFrame,
                                 text="Notes:",
                                 font=BaseView.NORMAL_FONT)
        self._notesFrame = Frame(self._rightFrame)
        self._notesText = Text(self._notesFrame,
                               width=50,
                               height=4,
                               state=DISABLED,
                               wrap=WORD,
                               font=BaseView.NORMAL_FONT)
        self._notesScroll = Scrollbar(self._notesFrame,
                                      command=self._notesText.yview)
        self._notesText.config(yscrollcommand=self._notesScroll.set)

        # bottom
        self._sep1 = Separator(self, orient="horizontal")
        self._invLabel = Label(self,
                               text="Inventory:",
                               font=BaseView.NORMAL_FONT)
        self._invFrame = Frame(self)
        self._inventory = Treeview(
            self._invFrame,
            columns=["type", "price", "qty", "stockDays"],
            selectmode="browse",
            height=15)
        self._inventory.heading("#0", text="Item", anchor=N + W)
        self._inventory.column("#0", width=300, anchor=N + W, stretch=True)
        self._inventory.heading("type", text="Type", anchor=N + W)
        self._inventory.column("type", width=100, anchor=N + W)
        self._inventory.heading("price", text="Price", anchor=N + W)
        self._inventory.column("price", width=60, anchor=N + W)
        self._inventory.heading("qty", text="Qty", anchor=N + W)
        self._inventory.column("qty", width=40, anchor=N + W)
        self._inventory.heading("stockDays", text="Stock Days", anchor=N + W)
        self._inventory.column("stockDays",
                               width=200,
                               anchor=N + W,
                               stretch=True)
        self._invScroll = Scrollbar(self._invFrame,
                                    command=self._inventory.yview)
        self._inventory.config(yscrollcommand=self._invScroll.set)

        # placement: scrollbars
        self._descText.grid(row=0, column=0, sticky=N + W + E + S)
        self._descScroll.grid(row=0, column=1, sticky=N + S)
        self._notesText.grid(row=0, column=0, sticky=N + W + E + S)
        self._notesScroll.grid(row=0, column=1, sticky=N + S)
        self._inventory.grid(row=0, column=0, sticky=N + W + E + S)
        self._invScroll.grid(row=0, column=1, sticky=N + S)

        # placement: left frame
        self._imgLabel.grid(row=0, column=0, sticky=N + W + E + S)
        self._locLabel.grid(row=1, column=0, sticky=N + W)
        self._locPreview.grid(row=2, column=0, sticky=W + E)

        # placement: right frame
        self._nameLabel.grid(row=0, column=0, sticky=W)
        self._descLabel.grid(row=1, column=0, sticky=W)
        self._descFrame.grid(row=2, column=0, sticky=W)
        self._notesLabel.grid(row=3, column=0, sticky=W)
        self._notesFrame.grid(row=4, column=0, sticky=W)

        # bottom
        self._sep1.grid(row=1, column=0, columnspan=2, sticky=W + E)
        self._invLabel.grid(row=2, column=0, columnspan=2, sticky=N + W)
        self._invFrame.grid(row=3, column=0, columnspan=2, sticky=W + E)

        self._leftFrame.grid(row=0, column=0, sticky=N + W)
        self._rightFrame.grid(row=0, column=1, sticky=N + W)

    ########
    # Add callbacks for all GUI element events and Tkinter variables.
    def _bind_widgets(self):

        self._locPreview.bind("<Double-Button-1>", self._open_loc)
        self._inventory.bind("<Double-Button-1>",
                             self._inventory_on_double_click)

    ########
    # Populates all GUI elements with new data.
    def populate(self, data):
        self._data = data
        if data == None:  # null check
            self.set_defaults()
            return
        for k, v in data.items():
            if k == "name":
                # non-null
                self._nameLabel.config(text=v)
            elif k == "img":
                if v == None:  # null check
                    v = BaseView.DEFAULT_IMG
                utility.update_img(self._imgLabel, v, maxSize=300)
            elif k == "location":
                # non-null
                self._locPreview.populate(v)
            elif k == "description":
                if v == None:  # null check
                    v = BaseView.EMPTY_STR
                utility.update_text(self._descText, v)
            elif k == "notes":
                if v == None:  # null check
                    v = BaseView.EMPTY_STR
                utility.update_text(self._notesText, v)
            elif k == "sells":
                self._update_inventory()

    ########
    # Resets GUI elements to default values.
    def set_defaults(self):
        utility.update_img(self._imgLabel, BaseView.DEFAULT_IMG, maxSize=300)
        utility.update_text(self._descText, BaseView.EMPTY_STR)
        utility.update_text(self._notesText, BaseView.EMPTY_STR)

    ########
    # Populates inventory with correct values
    def _update_inventory(self):
        allItems = self._inventory.get_children()
        for item in allItems:
            self._inventory.delete(item)
        self._imgs = []
        if self._data == None:
            return
        for entry in self._data["sells"]:
            img = entry["item"]["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["item"]["name"]
            fields = [
                BaseView.TYPE_MAP[entry["item"]["type"]], entry["price"],
                entry["qty"], entry["stockDays"]
            ]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._imgs.append(img)
            self._inventory.insert("",
                                   END,
                                   image=img,
                                   text=name,
                                   values=fields)

    ########
    # Opens location view through refBook.
    def _open_loc(self, *args, **kwargs):
        if self._refBook == None or self._data == None:
            return
        self._refBook.show_location(self._data["location"]["name"])

    ########
    # Callback for double clicking in inventory treeview.
    def _inventory_on_double_click(self, *args, **kwargs):
        if self._refBook == None or self._data == None or len(
                self._inventory.selection()) == 0:
            return
        self._refBook.show_item(self._data["sells"][self._inventory.index(
            self._inventory.selection())]["item"]["name"])
Exemple #26
0
tv['columns'] = ('temperature', 'light', 'soil', 'rainfall', 'land')
#tv['columns'] = ('starttime', 'endtime', 'status')
tv.heading("#0", text='Crop', anchor="center")
tv.column("#0", anchor=W, width=60)
tv.heading('temperature', text='Temperature')
tv.column('temperature', anchor='center', width=95)
tv.heading('light', text='Light')
tv.column('light', anchor='center', width=65)
tv.heading('soil', text='Soil')
tv.column('soil', anchor='center', width=50)
tv.heading('rainfall', text='Rainfall')
tv.column('rainfall', anchor='center', width=75)
tv.heading('land', text='Land', anchor=W)
tv.column('land', anchor=W, width=75)
#tv.grid(row=10,column=0,sticky = (N,S,W,E))
tv.config(height=1)

#tv.tag_configure('test',background='red')
tv.grid(row=10, columnspan=3)
tv.grid_rowconfigure(10, weight=1)

label2.grid(row=13, column=1)
"""
lb.grid(row=15,column=1)
lb.config(height=10)
for i in range(100):
    lb.insert(END, i)
lb.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=lb.yview)

"""
Exemple #27
0
class show:
    def __init__(self):
        self.window=Tk()
        self.window.title("Show | Sales Products")
        self.window.iconbitmap('shop.ico')
        self.window.geometry("1365x670+0+0")
        self.window.maxsize(1365,670)
        self.window.minsize(1365,670)
        # self.window.resizable(width=False,height=False)
    def add_background(self):
        self.image = Image.open("images/back.jpg")
        self.image = self.image.resize((1365, 700), Image.ANTIALIAS)
        self.img = ImageTk.PhotoImage(self.image)
        self.li = Label(image = self.img, text="TALHA")
        self.li.image = self.img
        self.li.pack()
        self.Menubar()

    def Menubar(self):
        self.menubar = Menu()
        self.menuitems_add = Menu(self.menubar, tearoff=0,bg="blue",fg="white")
        self.menuitems_add.add_command(label="Add Products", command=self.add_products)
        # self.menuitems.add_separator()

        self.menuitems_sales = Menu(self.menubar, tearoff=0,bg="blue",fg="white")
        self.menuitems_sales.add_command(label="Sale Products", command=self.sales_products)

        self.menuitems_customer = Menu(self.menubar, tearoff=0, bg="blue", fg="white")
        self.menuitems_customer.add_command(label="Add Customer", command=self.add_customer)
        self.menuitems_customer.add_command(label="Show Customer Records", command=self.customer_record)

        self.menuitems_reports = Menu(self.menubar, tearoff=0, bg="blue", fg="white")
        self.menuitems_reports.add_command(label="Check Products Quantity", command=self.check_products_quantity)
        self.menuitems_reports.add_command(label="Check Profit/Loss", command=self.check_profit_loss)
        self.menuitems_reports.add_command(label="Check Sales Products", command=self.check_products_sales)
        self.menuitems_reports.add_command(label="Check Sent Amount Details", command=self.check_amount)

        self.menubar.add_cascade(label="Add Products", menu=self.menuitems_add)
        self.menubar.add_cascade(label="Sales Products", menu=self.menuitems_sales)
        self.menubar.add_cascade(label="Customer", menu=self.menuitems_customer)
        self.menubar.add_cascade(label="Reports", menu=self.menuitems_reports)
        self.menubar.add_cascade(label="Exit", command=quit)
        self.window.config(menu=self.menubar)

    def add_table(self):
        self.l1=Label(self.window,text="**Sales Details**",font="Courier 25 bold",bg="black",fg="white",width=61)
        self.l1.place(x=82,y=20)

        self.l1 = Label(self.window, text="Developed by : Muhammad Talha | NTU", font="Courier 10 bold")
        self.l1.place(x=470, y=610)

        self.l1 = Label(self.window, text="Enter Product Name:", font="courier 16 bold",bg="blue",fg="white")
        self.l1.place(x=280, y=90)

        self.Entry_reg = Entry(self.window, font="courior 14 bold")
        self.Entry_reg.place(x=550, y=90, height=30)

        self.b1 = Button(self.window, text="Search", font="Times 13 bold",fg="white",bg="blue",width=10)
        self.b1.place(x=790, y=90)
        self.b1.bind('<Button-1>', self.search_product)


        # for Style Table
        style = Style()
        style.configure("mystyle.Treeview", highlightthickness=0, bd=0,
                        font=('courier 12 bold'),rowheight=43)  # Modify the font of the body
        style.configure("mystyle.Treeview.Heading", font=('Times 15 bold'),foreground="black")  # Modify the font of the headings
        # style.layout("mystyle.Treeview", [('mystyle.Treeview.treearea', {'sticky': 'nswe'})])  # Remove the borders
        # import TreeViewe
        self.tr=Treeview(self.window,columns=('A','B','C','D','E'),selectmode="extended",style='mystyle.Treeview')
        # heading key+text
        self.tr.heading("#0", text="Sr.No")
        self.tr.column("#0", minwidth=0, width=85, stretch=NO)

        self.tr.heading("#1",text="Product Name")
        self.tr.column("#1",minwidth=0,width=160,stretch=NO)

        self.tr.heading("#2", text="Product Catagory")
        self.tr.column("#2", minwidth=0, width=200, stretch=NO)

        self.tr.heading("#3", text="Quantity")
        self.tr.column("#3", minwidth=0, width=175, stretch=NO)

        self.tr.heading("#4", text="Price Per Product")
        self.tr.column("#4", minwidth=0, width=175, stretch=NO)

        self.tr.heading("#5", text="Sales Price")
        self.tr.column("#5", minwidth=0, width=160, stretch=NO)

        j=1
        for i in Database.show_sales_details():
            self.tr.insert('',index=j,text=j,values=(i[1],i[2],i[3],i[4],i[5]))
            j+=1

        self.Entry_reg.bind('<KeyRelease>', self.remove)

        self.sb = Scrollbar(self.tr)
        self.sb.place(x=935,y=2,height=452,width=22,bordermode=OUTSIDE)
        self.sb.config(command=self.tr.yview)
        self.tr.config(yscrollcommand=self.sb.set)
        self.tr.place(x=170,y=150)

        # to excel file
        self.b1 = Button(self.window, text="Save to Excel", font="Times 12 bold",bg="blue",fg="white",width=20,
        )
        self.b1.place(x=938, y=610)
        self.b1.bind('<Button-1>', self.excel)


        self.window.mainloop()


    def remove(self,event):
        for row in self.tr.get_children():
            self.tr.delete(row)
        j = 1
        for i in Database.show_sales_details():
            self.tr.insert('', index=j, text=j, values=(i[1], i[2], i[3], i[4], i[5]))
            j += 1

    def search_product(self,event):
        try:
            data = (self.Entry_reg.get(),)
            if self.Entry_reg.get() == "":
                msg.showwarning("Message ! ", "please insert product name !")
            else:
                j = 1
                D = Database.search_details_sales_table(data)
                if D:
                    for row in self.tr.get_children():
                        self.tr.delete(row)
                    self.Entry_reg.delete(0, END)
                    for i in D:
                        self.tr.insert('', index=j, text=j, values=(i[1],i[2],i[3],i[4],i[5]))
                        j += 1
                else:
                    msg.showwarning("Message!", "No result Found!")

        except:
            msg.showwarning("Error!", "Something went wrong! please contact with developer !!!")
    def excel(self,event):
        try:
            x=Database.show_sales_details()
            p_name=[]
            p_catagory=[]
            p_quantity=[]
            price=[]
            p_sales_price=[]
            for i in range(len(x)):
                z=x.__getitem__(i)
                p_name.append(z[1])
                p_catagory.append(z[2])
                p_quantity.append(z[3])
                price.append(z[4])
                p_sales_price.append(z[5])

            products = pd.DataFrame({
                "Product Name": p_name,
                "Product Catagory":p_catagory,
                "Quantity":p_quantity,
                "Price Per Product":price,
                "Sales Price":p_sales_price
            })

            with pd.ExcelWriter("Excel Files/Sales_Products_Records.xlsx") as writer:
                products.to_excel(writer, sheet_name="Sales_Products", index=False)
            msg.showinfo("Message ! ", "Your data has been inserted Susccessfully !")
        except:
            msg.showwarning("Message!","Something Went Wrong!please contact with developer!!!")

    def add_products(self):
        self.window.destroy()
        home = Home.data()
        home.add_background()
        home.add_frame()

    def sales_products(self):
        self.window.destroy()
        showP = Showing_Records.show()
        showP.add_background()
        showP.add_table()
    def check_products_quantity(self):
        self.window.destroy()
        showP = Check_Products_Quantity.show()
        showP.add_background()
        showP.add_table()
    def check_products_sales(self):
        pass

    def check_amount(self):
        self.window.destroy()
        showP = Check_Amount_Details.show()
        showP.add_background()
        showP.add_table()
    def check_profit_loss(self):
        self.window.destroy()
        showP = Check_Profit_Loss_GUI.show()
        showP.add_background()
        showP.add_table()
    def add_customer(self):
        self.window.destroy()
        home = Add_Customer.data()
        home.add_background()
        home.add_frame()
    def customer_record(self):
        self.window.destroy()
        showP = Customer_Records.show()
        showP.add_background()
        showP.add_table()
Exemple #28
0
class GUI:
    """
    Graphical User Interface, makes the communication easier for the bus driver in order to reduce the time the
    driver has to put into communicating with the system.

    designed in a 3 color scheme, black, green, and white
    has a background glow thats used to show the bus driver important updates, that need his attention
    default color is green, changes the color to red when there's a passenger that needs to be picked up
    and changes the color to gray when the bus is offline.

    has a welcome window that his purpose is to acquire some information regarding the bus from the driver.
    3 entries that get the Bus ID, the line number and the starting station of the bus.
    And a Finish Button that saves the information and starts the bus system with the given information
    After the finish is clicked, the window will close and a loading screen is displayed while the main window is loading.

    the main window holds on top a display that shows the locations of all the relevant buses and passengers.
    Next Station button that moves the bus to the next station.
    a square with the purpose to make sure that the bus will stop at the station if there's a passengers.
    server broadcasts section that shows all the messages recieved from the server
    place to send messages to the server that consists of a send button and an entry to type the text into.
    also displays some statistics.
    and a big red exit button.
    """

    __BLACK = "#000000"
    __GREEN = "#105e29"
    __GREEN1 = "#1DB954"

    def __init__(self):
        """
        creates a GUI class instance
        :return: GUI
        """

        self.__line, self.__id, self.__station = None, None, None
        self.__bus = None
        self.__font_name = "Bahnschrift SemiBold SemiConden"
        self.__headlines = None
        self.asking_to_reconnect = False
        self.__passengers_count_stringvar = None
        self.__buses_count_stringvar = None
        self.__session_time_stringvar = None

        self.__window = None
        self.__finished_window = None
        self.__lost_connection_window = None
        self.__kicked_window = None

        self.__server_broadbast_stringvars_dict = dict()
        #those dictionaries store the location regarding plament widget groups on the screen
        self.__statistics_coords = {"x": 540, "y": 408}
        self.__updating_statistics_coords ={"x": 680, "y": 331}
        self.__next_btn_coords = {"x": 29, "y": 177}
        self.__exit_btn_coords = {"x": 29, "y": 490}
        self.__broadcast_section_coords = {"x": 44, "y": 427}
        self.__server_messages_coords =  {"x": 66, "y": 322, "jump": 34}
        self.__table_coords = {"x": 26, "y": 74, "width" : 744, "height":59}


    def start(self):
        """
        starts the gui
        starts by asking for starting information for the bus, after that creates a bus instance with the given information
        after that starts the loading process for the rest of the program components.
        :return: None
        """

        self.config_first_data()
        if self.__line == None:
            sys.exit("Ended by user")


        self.__window = Tk()
        self.__window.iconbitmap(f'images bus\\icon.ico')  # put stuff to icon
        self.__window.title("Bus Client")
        self.__window.resizable(OFF, OFF)
        self.__start_loading_screen()
        self.__window.mainloop()
        self.stop()

    def stop(self):
        """
        stops the run of the gui and tells the bus to stop as well.
        at the end closes the code
        :return: None
        """

        self.__bus.stop = True
        if self.__finished_window != None and self.__finished_window.state() == "normal":
            self.__finished_window.destroy()
        if self.__window != None and self.__window.state() == "normal":
            self.__window.destroy()
        if self.__lost_connection_window != None and self.__lost_connection_window.state() == "normal":
            self.__lost_connection_window.destory()
        if self.__kicked_window != None and self.__kicked_window.state() == "normal":
            self.__kicked_window.destroy()
        sys.exit("closed by user")

    def __start_loading_screen(self):
        """
        Starts the loading proccess.
        At first shows the loading image, waits for 10ms and then
        starts loading all the widgets and the properties of the program.
        :return: None
        """

        loading_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\loading screen.png"))
        self.__window.geometry(f"{loading_img.width()}x{loading_img.height()}")
        self.__bg_label = Label(self.__window, image=loading_img, bg="#192b3d")
        self.__bg_label.place(x=0, y=0)
        self.__window.after(10, self.__finish_loading_screen)
        self.__window.mainloop()

    def __finish_loading_screen(self, launch_bus=True):
        """
        starts the bus object, places all the labels, buttons, data tables, entries
        and initializes all the values needed for the rest of the run
        :return: False
        """
        if launch_bus:
            self.__bus = Bus(self, self.__id, self.__line, self.__station)
            self.__bus.start()
        self.__headlines = [str(x) for x in range(1, self.__bus.max_number_of_stations + 1)]
        self.__passengers_count_stringvar = StringVar()
        self.__buses_count_stringvar = StringVar()
        self.__server_broadbast_stringvar1 = StringVar()
        self.__server_broadbast_stringvar2 = StringVar()
        self.__session_time_stringvar = StringVar()
        #init all the images
        self.__bg_nobody_is_waiting_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\nobody is waiting.png"))
        self.__bg_lost_connection_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\lost connection.png"))
        self.__bg_stop_at_the_next_station_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\stop at the next station.png"))
        self.__next_btn_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\next station.png"))
        self.__exit_btn_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\exit btn.png"))
        self.__send_btn_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\send btn.png"))
        #place the widgets on the window
        self.__create_table()
        self.__update_table()
        self.__place_buttons()
        self.__place_labels()
        self.__place_free_text_section()
        self.__window.geometry(f"{self.__bg_nobody_is_waiting_img.width()}x{self.__bg_nobody_is_waiting_img.height()}")
        self.__update_bg()
        #start the updates loop that will keep the widgets updated
        self.__loop()

    def __create_table(self):
        """
        creates and places the table that display the locations of the buses and the passengers for the line.
        uses the ttk. widgets Treeview combined with a scrollbar.
        and the ThemedStyle lib in order to give the dark themed look to the widget.
        :return: None
        """

        base_x = self.__table_coords["x"]
        base_y = self.__table_coords["y"]
        base_width = self.__table_coords["width"]
        base_height = self.__table_coords["height"]
        self.__tree_style = ThemedStyle(self.__window)
        self.__tree_style.set_theme("black")
        self.__tree_style.configure("mystyle.Treeview", highlightthickness=0, bd=0,
                                    font=(self.__font_name, 11))  # Modify the font of the body
        self.__tree_style.configure("mystyle.Treeview", background="black",
                                    fieldbackground="black", foreground=GUI.__GREEN1)
        self.__tree_style.configure("mystyle.Treeview.Heading", font=(self.__font_name, 13, 'bold'),
                                    foreground=GUI.__GREEN1)  # Modify the font of the headings
        scrollX = ttk.Scrollbar(self.__window, orient=HORIZONTAL)
        self.__tree = Treeview(self.__window, show="headings", columns=self.__headlines, xscrollcommand=scrollX.set, style = "mystyle.Treeview")
        self.__tree.place(x=base_x, y=base_y, width=base_width, height=base_height)
        scrollX.config(command=self.__tree.xview)
        scrollX.place(x=base_x, y=base_y+base_height, width=base_width)

    def __place_buttons(self):
        """
        Places the main buttons on the screen.
            next_button - tells the bus to move onto the next station and tell the server that he moved
            exit_button - closes the gui and the server
        :return: None
        """

        self.__next_button = tkinter.Button(self.__window, image=self.__next_btn_img, command=self.__bus.next_station, borderwidth=0, background = "#000000", activebackground = "#083417")
        self.__next_button.place(x=self.__next_btn_coords["x"], y=self.__next_btn_coords["y"])
        self.__exit_button = tkinter.Button(self.__window, command=self.stop, image=self.__exit_btn_img, borderwidth=0,
                                            background=GUI.__BLACK, activebackground=GUI.__BLACK, fg="red")
        self.__exit_button.place(x=self.__exit_btn_coords["x"], y=self.__exit_btn_coords["y"])

    def __update_labels(self):
        """
        updates all the labels in the program
            passenger count - shows how many passengers are waiting for the bus
            buses count - shows how many buses are active in the line
            session time - displays the session time of the driver
            server messages -  shows the messages received from the server

        updates the StringVars instead of recreating the label.
        the messages label is actually more than just 1 label, but all the labels and the StringVars are stored in the same dict
        the reason is that breaking down the messages into a couple layers allows more flexible formatting
        :return: None
        """

        #statistics
        self.__passengers_count_stringvar.set(str(self.__bus.count_people()))
        self.__buses_count_stringvar.set(str(self.__bus.count_buses()))
        self.__session_time_stringvar.set(f"{self.__bus.session_time}")
        #server messages
        messages = []
        for message in self.__bus.server_free_text_messages:
            if time.time() - message["time"] > Bus.MESSAGE_TTL: #Removes old messages
                self.__bus.server_free_text_messages.remove(message)
            messages.append(f"{time.strftime('%H:%M:%S', time.localtime(message['time']))}: {message['text']} \n")
        #makes sure that all the labels will be addressed, if there's not enough information for them fills with ""
        while len(messages) <Bus.MAX_MESSAGE_COUNT:
            messages.append("")
        #updates the StringVars
        for i in range(0,Bus.MAX_MESSAGE_COUNT):
            self.__server_broadbast_stringvars_dict[i].set(messages[i])

    def __loop(self):
        """
        the main GUI loop, run in the main thread and updates data on the screen (labels, table and background)
        runs twice per second but can be easily changes if needed
        will stop looping only when the self.__bus.stop is equal to True
        :return: None
        """

        if self.__bus.stop:
            return
        try:
            self.__update_table()
            self.__update_bg()
            self.__update_labels()
            self.__after_job = self.__window.after(500, self.__loop)
        except Exception as e:
            print(f"Done looping because: {e}")

    def __place_labels(self):
        """
        creates labels, configures them and places them at the places they're supposed to be.
        labels that are placed
            - passengers_count      shows the passengers count in the line
            - buses_count           shows the bus count of the buses in the line
            - server_messages       shows the messages received from the server
            - line_label            shows the line number
            - id_label              shows the bus id
            - session_time_label    shows the session time
        :return: None
        """

        # statistics labels
        self.__passengers_count_stringvar.set(str(self.__bus.count_people()))
        self.__buses_count_stringvar.set(str(self.__bus.count_buses()))
        #changing statistics
        base_x = self.__updating_statistics_coords["x"]
        base_y = self.__updating_statistics_coords["y"]
        passengers_count_label = Label(self.__window, textvariable=self.__passengers_count_stringvar, fg=GUI.__GREEN,
                                       bg=GUI.__BLACK, font=(self.__font_name, 13, "bold"))
        buses_count_label = Label(self.__window, textvariable=self.__buses_count_stringvar, fg=GUI.__GREEN, bg=GUI.__BLACK,
              font=(self.__font_name, 13, "bold"))
        passengers_count_label.place(x=base_x, y=base_y)
        buses_count_label.place(x=base_x + 42, y=base_y + 28)
        #broadcasts
        base_x =self.__server_messages_coords["x"]
        base_y = self.__server_messages_coords["y"]
        jump = self.__server_messages_coords["jump"]
        for i in range(0,Bus.MAX_MESSAGE_COUNT):
            self.__server_broadbast_stringvars_dict[i] = StringVar()
            Label(self.__window, fg=GUI.__GREEN, bg = GUI.__BLACK, font=(self.__font_name, 15, "bold"), textvariable=self.__server_broadbast_stringvars_dict[i]).place(x=base_x, y=base_y+jump*i)
        # statistics
        base_x = self.__statistics_coords["x"]
        base_y = self.__statistics_coords["y"]
        Label(self.__window, text=str(self.__line), fg=GUI.__GREEN, bg = GUI.__BLACK, font=(self.__font_name, 12, "bold")).place(x=base_x, y=base_y)
        Label(self.__window, text=str(self.__id), fg=GUI.__GREEN, bg = GUI.__BLACK, font=(self.__font_name, 12, "bold")).place(x=base_x-14, y=base_y+20)
        Label(self.__window, textvariable=self.__session_time_stringvar, fg=GUI.__GREEN, bg=GUI.__BLACK, font=(self.__font_name, 12, "bold")).place(x=base_x+37, y=base_y+39)

    def __place_free_text_section(self):
        """
        places the free text section
        has a button and an entry that will send messages to the server if needed
        upon a button click the data in the entry will be sent to the server as a message from the bus.
        :return: None
        """

        self.__message_entry = Entry(self.__window, width = 30, borderwidth=0, background = "black", insertbackground ="#1DB954", foreground="#1DB954",font = (self.__font_name, 14))
        self.__send_broadcast_button = Button(self.__window, image=self.__send_btn_img, borderwidth=0, background = "#000000", activebackground = "#083417", command=self.__send_free_text_to_server)
        base_x =self.__broadcast_section_coords["x"]
        base_y =self.__broadcast_section_coords["y"]
        self.__message_entry.place(x=base_x, y=base_y)
        self.__send_broadcast_button.place(x=base_x-3, y=base_y +29)

    def __send_free_text_to_server(self):
        """
        harvests the data from the self.__message_entry, clears the entry
        then tells the bus to send the message to the server
        :return: None
        """

        if self.__bus.connected:
            data = self.__message_entry.get()
            print(f"broad casting data: {data}")
            if not self.__bus.send_free_text(data):
                print("failed to send")
            else:
                self.__message_entry.delete(0, 'end')

        else:
            print("failed to send")

    def __update_table(self):
        """
        recalculates the way the display table is supposed to look and places all the widgets into the table.
        :return: None
        """

        self.__headlines = [str(x) for x in range(1, self.__bus.max_number_of_stations + 1)]
        self.__tree.config(columns=self.__headlines)
        for headline in self.__headlines:
            self.__tree.heading(headline, text=headline)
            self.__tree.column(headline, anchor="center", stretch=False, width=47)
        data = self.__bus.display_passengers()
        for i in self.__tree.get_children():
            self.__tree.delete(i)
        self.__tree.insert("", END, values=data)

    def __update_bg(self):
        """
        changes the background according to the state of the bus
        currently has only 3 states but more states can be easily added
        nobody is waiting - will display a greenish background with the message "nobody is waiting" when there are no passengers waiting
        stop at the next station - will display a red background with the message "somebody is waiting" when there's a passenger at the next station
        lost connection - will display a gray background with the message "lost connection" when the bus loses connection or gets kicked.
        :return: None
        """

        if self.__bus.connected and not self.__bus.kicked:
            if self.__bus.next_station_people_count==0:
                self.__bg_label["image"] = self.__bg_nobody_is_waiting_img
            elif self.__bus.next_station_people_count > 0:
                self.__bg_label["image"] = self.__bg_stop_at_the_next_station_img
        else:
            self.__bg_label["image"] = self.__bg_lost_connection_img

    def display_lost_connection(self):
        """
        creates a window saying that the bus has lost connection to the server
        has a button that says "Reconnect" and will try to reconnect to the server.
        if failed to reconnect a new message will show saying "failed to reestablish connection to the server"
        :return: None
        """

        if self.__bus.stop == True:
            return
        self.__lost_connection_window = Tk()
        self.__lost_connection_popup_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\Lost connection popup.png"),master=self.__lost_connection_window)
        self.__lost_connection_window.geometry(f"{self.__lost_connection_popup_img.width()}x{self.__lost_connection_popup_img.height()}")
        self.__lost_connection_window.iconbitmap(r'Images bus\icon.ico')  # put stuff to icon
        self.__lost_connection_window.title("Lost Connection to the server")
        self.__lost_connection_window.resizable(OFF, OFF)
        self.__bg_label_lost_connection = Label(self.__lost_connection_window, image=self.__lost_connection_popup_img, bg="white")
        self.__bg_label_lost_connection.place(x=0, y=0)
        self.__reconnect_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\reconnect.png"), master=self.__lost_connection_window)
        self.__reconnect_button = tkinter.Button(self.__lost_connection_window, command=lambda: self.__try_to_reconnect("PostLogin"), image=self.__reconnect_img, borderwidth =0, activebackground="white")
        self.__reconnect_button.place(x=152, y=101)
        self.__lost_connection_window.mainloop()
        if not self.__bus.connected:
            sys.exit("closed by user")

    def failed_to_connect(self, firstattempt = True):
        """
        creates a window saying that the bus has failed to establish the first connection to the server.
        has a button that says "Reconnect" and will try to reconnect to the server.
        if failed to reconnect a new message will show saying "failed to reestablish connection to the server"
        :return: None
        """

        if self.__bus.stop == True:
            return
        if not firstattempt:
            self.__failed_to_reconnect_img = ImageTk.PhotoImage(
                PIL.Image.open(r"Images bus\failed to reestablish.png"),
                master=self.__failed_to_connect_window)
            self.__bg_label_failed_to_connect["image"] = self.__failed_to_reconnect_img
            return

        self.__failed_to_connect_window = Tk()
        self.__failed_to_connect_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\failed to establish.png"),
                                                          master=self.__failed_to_connect_window)
        self.__failed_to_connect_window.geometry(
            f"{self.__failed_to_connect_img.width()}x{self.__failed_to_connect_img.height()}")
        self.__failed_to_connect_window.iconbitmap(r'Images bus\icon.ico')  # put stuff to icon
        self.__failed_to_connect_window.title("Failed To Connect")
        self.__failed_to_connect_window.resizable(OFF, OFF)
        self.__bg_label_failed_to_connect = Label(self.__failed_to_connect_window, image=self.__failed_to_connect_img,
                                                  bg="white")
        self.__bg_label_failed_to_connect.place(x=0, y=0)

        self.__reconnect_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\reconnect.png"),
                                                  master=self.__failed_to_connect_window)
        self.__reconnect_button = tkinter.Button(self.__failed_to_connect_window,
                                                 command=lambda: self.__try_to_reconnect("PreLogin"),
                                                 image=self.__reconnect_img, borderwidth=0, activebackground="white")
        self.__reconnect_button.place(x=152, y=101)

        self.__failed_to_connect_window.mainloop()
        if not self.__bus.connected:
            sys.exit("closed by user")

    def display_kicked(self, reason: str):
        """
        creates a window saying that the bus has been kicked from the server
        has a button that says "Reconnect" and will try to reconnect to the server.
        if failed to reconnect a new message will show saying "failed to reestablish connection to the server".
        takes the reason that the bus had been kicked as a parameter,
        currently has no use, but here to make future development easier.
        :param reason: str
        :return: None
        """

        if self.__bus.stop == True:
            return
        self.__kicked_window = Tk()
        self.__kicked_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\kicked.png"),master=self.__kicked_window)
        self.__kicked_window.geometry(f"{self.__kicked_img.width()}x{self.__kicked_img.height()}")
        self.__kicked_window.iconbitmap(r'Images bus\icon.ico')  # put stuff to icon
        self.__kicked_window.title("kicked")
        self.__kicked_window.resizable(OFF, OFF)
        self.__bg_label_kicked = Label(self.__kicked_window, image=self.__kicked_img, bg="white")
        self.__bg_label_kicked.place(x=0, y=0)

        self.__reconnect_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\reconnect.png"), master=self.__kicked_window)
        self.__reconnect_button = tkinter.Button(self.__kicked_window, command=lambda: self.__try_to_reconnect("Kicked"), image=self.__reconnect_img, borderwidth =0, activebackground="white")
        self.__reconnect_button.place(x=152, y=101)
        self.__kicked_window.mainloop()
        if not self.__bus.connected:
            sys.exit("closed by user")

    def display_finished(self):
        """
        opens a window that shows the finished image and all the statistics that come with it.
        shows the session time, and how many people the bus picked up during his ride.
        has an exit button that closes the program and ends the session.
        used as the last window in the program, nothing will open after this window is closed.
        return: None
        """

        self.__window.after_cancel(self.__after_job)
        self.__window.destroy()
        finished_font = ("Bauhaus 93", 30)
        self.__finished_window = Tk()
        self.__finished_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\finished.png"))
        self.__finished_exit_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\exit finished.png"))
        self.__finished_window.geometry(f"{self.__finished_img.width()}x{self.__finished_img.height()}")
        self.__finished_window.iconbitmap(r'Images bus\icon.ico')  # put stuff to icon
        self.__finished_window.title("Finished")
        self.__finished_window.resizable(OFF, OFF)
        bg_label = Label(self.__finished_window, image=self.__finished_img, bg="#1DB954")
        bg_label.place(x=0, y=0)
        self.__people_count_label = Label(self.__finished_window, text=str(self.__bus.total_people_count), bg="#1DB954",
                                          fg="#000000", font=finished_font)
        self.__session_time_label = Label(self.__finished_window, text=str(self.__bus.session_time), fg="#1DB954",
                                          bg="#000000", font=finished_font)
        self.__finish_button = tkinter.Button(self.__finished_window, image=self.__finished_exit_img, command=self.stop,
                                              borderwidth=0, activebackground="gray", fg="red")

        self.__finish_button.place(x=276, y=462)
        self.__people_count_label.place(x=494, y=190)
        self.__session_time_label.place(x=560, y=320)

        self.__finished_window.mainloop()
        if not self.__bus.connected:
            sys.exit("closed by user")

    def __try_to_reconnect(self, status):
        """
        tries to reconnect the bus back to the server
        takes the status of the program when the command was called, can be "PreLogin"\"PostLogin"\"Kicked"
        used in case if failed to reconnect, it makes sure that the correct window will be updated.
        :param status: str
        return: Bool
        """
        if status == "PreLogin":
            if self.__bus.start(first_attempt = False):
                self.__finish_loading_screen(launch_bus=False)
                self.__failed_to_connect_window.destroy()

        elif self.__bus.reconnect():
            if status =="PostLogin":
                self.__lost_connection_window.destroy()
            elif status == "Kicked":
                self.__kicked_window.destroy()
            else:
                print(f"ughh..... i dunno what to do, status: {status} unrecognized")
            self.__bus.asking_user_to_reconnect = False
        else:
            if status == "PostLogin":
                self.__failed_to_reconnect_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\failed to reestablish.png"),
                                                          master=self.__lost_connection_window)
                self.__bg_label_lost_connection["image"]=self.__failed_to_reconnect_img
            elif status == "Kicked":
                self.__failed_to_reconnect_img = ImageTk.PhotoImage(
                    PIL.Image.open(r"Images bus\failed to reestablish.png"),
                    master=self.__kicked_window)
                self.__bg_label_kicked["image"] = self.__failed_to_reconnect_img
            else:
                print(f"ughh..... i dunno what to do, status: {status} unrecognized")

    def config_first_data(self):
        """
        the first thing that the uses sees when he runs the client.
        opens a window asking the user to give some information about the bus he's driving and the line he's working for
        has 3 entries and a finish button
         - id_entry         the bus id
         - line_entry       the line that the bus works for
         - station_entry    the station number that the driver starts from

         - finish_button    passes the entries to the __set_up_data method that takes the data, saves it and closes the window

        :return: None
        """
        window = Tk()
        back_ground_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\opening screen.png"))
        finish_img = ImageTk.PhotoImage(PIL.Image.open(r"Images bus\finish btn.png"))
        window.geometry(f"{back_ground_img.width()}x{back_ground_img.height()}")
        window.iconbitmap(f'images bus\\icon.ico')  # put stuff to icon
        window.title("User Setup")
        window.resizable(OFF, OFF)
        back_ground_label = Label(window, image=back_ground_img, bg=GUI.__BLACK)
        back_ground_label.place(x=0, y=0)
        station_entry = Entry(window, width=8, borderwidth=0, background = "black", foreground="#1DB954", insertbackground ="#1DB954", font = (self.__font_name, 22))
        station_entry.insert(END, "1")
        station_entry.place(x=570, y=397)
        id_entry = Entry(window, width=20, borderwidth=0, background = "black", foreground="#1DB954", insertbackground ="#1DB954", font = (self.__font_name, 22))
        id_entry.insert(END, str(random.randint(1, 11111111)))
        id_entry.place(x=295, y=247)
        line_entry = Entry(window, width=14, borderwidth=0, background = "black", foreground="#1DB954", insertbackground ="#1DB954", font = (self.__font_name, 22))
        line_entry.insert(END, "14")
        line_entry.place(x=484, y=323)
        finish_button = tkinter.Button(window, image =finish_img, activebackground=GUI.__GREEN, borderwidth=0, background = GUI.__GREEN,
                                       command=lambda: self.__set_up_data(id_entry, station_entry, line_entry, window))
        finish_button.place(x=299, y=478)
        window.mainloop()

    def __set_up_data(self, id_entry, station_entry, line_entry, window):
        """
        checks that all the values given match the expected (all of them are numbers)
        after that stores them as part of the class variables and and closes the given window

        in case if the given values don't match the expectation then a new window will be
        shown saying that the values must be numbers.
        :param id_entry: Entry
        :param station_entry: Entry
        :param line_entry: Entry
        :param window: Tk
        :return: None
        """

        try:
            self.__id = int(id_entry.get())
            self.__line = int(line_entry.get())
            self.__station = int(station_entry.get())
            window.destroy()
        except:
            error_window = Tk()
            error_window.geometry("200x80")
            error_window.iconbitmap(r'Images bus\icon.ico')  # put stuff to icon
            error_window.title("Error")
            error_window.resizable(OFF, OFF)
            error_window.configure(bg="red")
            error_label = Label(error_window, text="Error\n\nValues must be numbers")
            error_label.configure(bg="red")
            error_label.place(x=20, y=20)