Exemplo n.º 1
0
class TabContainer(QWidget):
    def __init__(self):
        super(TabContainer, self).__init__()
        self.next_item_is_table = False
        self.initUI()

    def initUI(self):
        self.setGeometry(150, 150, 650, 350)
        self.tabwidget = QTabWidget(self)
        vbox = QVBoxLayout()
        vbox.addWidget(self.tabwidget)
        self.setLayout(vbox)
        self.pages = []
        self.add_page()
        self.show()

    def create_page(self, *contents):
        page = QWidget()
        vbox = QVBoxLayout()
        print(contents)
        for c in contents:
            vbox.addWidget(c)
            print(c)

        page.setLayout(vbox)
        return page

    def create_table(self):
        rows, columns = random.randint(2, 5), random.randint(1, 5)
        table = QTableWidget(rows, columns)
        for r in range(rows):
            for c in range(columns):
                table.setItem(r, c, QTableWidgetItem(str(random.randint(0,
                                                                        10))))
        return table

    def create_list(self):
        list = QListWidget()
        columns = random.randint(2, 5)
        for c in range(columns):
            QListWidgetItem(str(random.randint(0, 10)), list)

        return list

    def create_new_page_button(self):
        # btn = QPushButton('Create a new page!')
        # btn.clicked.connect(self.add_page)
        # return btn

        # tabButton = QToolButton(self)
        # tabButton.setText('+')
        # font = tabButton.font()
        # font.setBold(True)
        # tabButton.setFont(font)
        # self.tabwidget.setCornerWidget(tabButton)
        # tabButton.clicked.connect(self.add_page)
        # return tabButton

        self.tabButton = QToolButton(self)
        self.tabButton.setText('+')
        font = self.tabButton.font()
        font.setBold(True)
        self.tabButton.setFont(font)
        # self.tabwidget.setCornerWidget(self.tabButton)
        self.tabButton.clicked.connect(self.add_page)

        return self.tabButton

    def add_page(self):
        if self.next_item_is_table:
            self.pages.append(
                self.create_page(self.create_table(),
                                 self.create_new_page_button()))
            self.next_item_is_table = False
        else:
            self.pages.append(
                self.create_page(self.create_list(),
                                 self.create_new_page_button()))
            self.next_item_is_table = True

        self.tabwidget.addTab(self.pages[-1], 'Page %s' % len(self.pages))
        self.tabwidget.setCurrentIndex(len(self.pages) - 1)
Exemplo n.º 2
0
class MainWidget(QTabWidget):

    """Custom main widget."""

    def __init__(self, parent=None, *args, **kwargs):
        """Init class custom tab widget."""
        super(MainWidget, self).__init__(parent=None, *args, **kwargs)
        self.parent = parent
        self.setTabBar(TabBar(self))
        self.setMovable(False)
        self.setTabsClosable(False)
        self.setTabShape(QTabWidget.Triangular)
        self.init_preview()
        self.init_corner_menus()
        self.init_tray()
        self.addTab(TabSearch(self), "Search")
        self.addTab(TabTool(self), "Tools")
        self.addTab(TabHtml(self), "HTML")
        self.addTab(TabSymbols(self), "Symbols")
        self._recent_tab = TabRecent(self)
        self.recentify = self._recent_tab.recentify  # shortcut
        self.addTab(self._recent_tab, "Recent")
        self.widgets_to_tabs(self.json_to_widgets(UNICODEMOTICONS))
        self.make_trayicon()
        self.setMinimumSize(QDesktopWidget().screenGeometry().width() // 1.5,
                            QDesktopWidget().screenGeometry().height() // 1.5)
        # self.showMaximized()

    def init_preview(self):
        self.previews, self.timer = [], QTimer(self)
        self.fader, self.previous_pic = FaderWidget(self), None
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(lambda: [_.close() for _ in self.previews])
        self.taimer, self.preview = QTimer(self), QLabel("Preview")
        self.taimer.setSingleShot(True)
        self.taimer.timeout.connect(lambda: self.preview.hide())
        font = self.preview.font()
        font.setPixelSize(100)
        self.preview.setFont(font)
        self.preview.setDisabled(True)
        self.preview.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)
        self.preview.setAttribute(Qt.WA_TranslucentBackground, True)

    def init_corner_menus(self):
        self.menu_1, self.menu_0 = QToolButton(self), QToolButton(self)
        self.menu_1.setText(" ⚙ ")
        self.menu_1.setToolTip("<b>Options, Extras")
        self.menu_0.setText(" ? ")
        self.menu_0.setToolTip("<b>Help, Info")
        font = self.menu_1.font()
        font.setBold(True)
        self.menu_1.setFont(font)
        self.menu_0.setFont(font)
        self.menu_tool, self.menu_help = QMenu("Tools Extras"), QMenu("Help")
        self.menu_tool.addAction(" Tools & Extras ").setDisabled(True)
        self.menu_help.addAction(" Help & Info ").setDisabled(True)
        self.menu_0.setMenu(self.menu_help)
        self.menu_1.setMenu(self.menu_tool)
        self.menu_tool.addAction("Explain Unicode", self.make_explain_unicode)
        self.menu_tool.addAction("Alternate Case Clipboard",
                                 self.alternate_clipboard)
        self.menu_tool.addSeparator()
        self.menu_tool.addAction("AutoCenter Window", self.center)
        self.menu_tool.addAction("Set Icon", self.set_icon)
        self.menu_tool.addAction(  # force recreate desktop file
            "Add Launcher to Desktop", lambda: set_desktop_launcher(
                "unicodemoticon", AUTOSTART_DESKTOP_FILE, True))
        self.menu_tool.addAction("Move to Mouse position",
                                 self.move_to_mouse_position)
        self.menu_tool.addSeparator()
        self.menu_tool.addAction("Minimize", self.showMinimized)
        self.menu_tool.addAction("Hide", self.hide)
        self.menu_tool.addAction("Quit", exit)
        self.menu_help.addAction("About Qt 5",
                                 lambda: QMessageBox.aboutQt(None))
        self.menu_help.addAction("About Unicodemoticon",
                                 lambda: open_new_tab(__url__))
        self.setCornerWidget(self.menu_1, 1)
        self.setCornerWidget(self.menu_0, 0)
        self.currentChanged.connect(self.make_tabs_previews)
        self.currentChanged.connect(self.make_tabs_fade)

    def init_tray(self):
        self.tray, self.menu = QSystemTrayIcon(self), QMenu(__doc__)
        self.menu.addAction("    Emoticons").setDisabled(True)
        self.menu.setIcon(self.windowIcon())
        self.menu.addSeparator()
        self.menu.setProperty("emoji_menu", True)
        list_of_labels = sorted(UNICODEMOTICONS.keys())  # menus
        menus = [self.menu.addMenu(_.title()) for _ in list_of_labels]
        self.menu.addSeparator()
        log.debug("Building Emoticons SubMenus.")
        for item, label in zip(menus, list_of_labels):
            item.setStyleSheet("padding:0;margin:0;border:0;menu-scrollable:1")
            font = item.font()
            font.setPixelSize(20)
            item.setFont(font)
            self.build_submenu(UNICODEMOTICONS[label.lower()], item)
        self.menu.addSeparator()
        self.menu.addAction("Alternate Case Clipboard",
                            self.alternate_clipboard)
        self.menu.addSeparator()
        self.menu.addAction("Quit", exit)
        self.menu.addAction("Show", self.showMaximized)
        self.menu.addAction("Minimize", self.showMinimized)
        self.tray.setContextMenu(self.menu)

    def build_submenu(self, char_list: (str, tuple), submenu: QMenu) -> QMenu:
        """Take a list of characters and a submenu and build actions on it."""
        submenu.setProperty("emoji_menu", True)
        submenu.setWindowOpacity(0.9)
        submenu.setToolTipsVisible(True)
        for _char in sorted(char_list):
            action = submenu.addAction(_char.strip())
            action.setToolTip(self.get_description(_char))
            action.hovered.connect(lambda _, ch=_char: self.make_preview(ch))
            action.triggered.connect(
                lambda _, char=_char: QApplication.clipboard().setText(char))
        return submenu

    def make_trayicon(self):
        """Make a Tray Icon."""
        if self.windowIcon() and __doc__:
            self.tray.setIcon(self.windowIcon())
            self.tray.setToolTip(__doc__)
            self.tray.activated.connect(
                lambda: self.hide() if self.isVisible()
                else self.showMaximized())
            return self.tray.show()

    def make_explain_unicode(self) -> tuple:
        """Make an explanation from unicode entered,if at least 1 chars."""
        explanation, uni = "", None
        uni = str(QInputDialog.getText(
            None, __doc__, "<b>Type Unicode character to explain?")[0]).strip()
        if uni and len(uni):
            explanation = ", ".join([self.get_description(_) for _ in uni])
            QMessageBox.information(None, __doc__, str((uni, explanation)))
        log.debug((uni, explanation))
        return (uni, explanation)

    def alternate_clipboard(self) -> str:
        """Make alternating camelcase clipboard."""
        return QApplication.clipboard().setText(
            self.make_alternate_case(str(QApplication.clipboard().text())))

    def make_alternate_case(self, stringy: str) -> str:
        """Make alternating camelcase string."""
        return "".join([_.lower() if i % 2 else _.upper()
                        for i, _ in enumerate(stringy)])

    def get_description(self, emote: str):
        description = ""
        try:
            description = unicodedata.name(str(emote).strip()).title()
        except ValueError:
            log.debug("Description not found for Unicode: " + emote)
        finally:
            return description

    def make_preview(self, emoticon_text: str):
        """Make Emoticon Previews for the current Hovered one."""
        log.debug(emoticon_text)
        if self.taimer.isActive():  # Be Race Condition Safe
            self.taimer.stop()
        self.preview.setText(" " + emoticon_text + " ")
        self.preview.move(QCursor.pos())
        self.preview.show()
        self.taimer.start(1000)  # how many time display the previews

    def json_to_widgets(self, jotason: dict):
        """Take a json string object return QWidgets."""
        dict_of_widgets, row = {}, 0
        for titlemotes in tuple(sorted(jotason.items())):
            tit = str(titlemotes[0]).strip()[:9].title()
            area = ScrollGroup(tit)
            layout = area.layout()

            grid_cols = 2 if tit.lower() == "multichar" else 8
            for index, emote in enumerate(tuple(set(list(titlemotes[1])))):
                button = QPushButton(emote, self)
                button.clicked.connect(lambda _, c=emote:
                                       QApplication.clipboard().setText(c))
                button.released.connect(self.hide)
                button.released.connect(lambda c=emote: self.recentify(c))
                button.pressed.connect(lambda c=emote: self.make_preview(c))
                button.setToolTip("<center><h1>{0}<br>{1}".format(
                    emote, self.get_description(emote)))
                button.setFlat(True)
                font = button.font()
                font.setPixelSize(50)
                button.setFont(font)
                row = row + 1 if not index % grid_cols else row
                layout.addWidget(button, row, index % grid_cols)

            dict_of_widgets[tit] = area
        return dict_of_widgets

    def widgets_to_tabs(self, dict_of_widgets: dict):
        """Take a dict of widgets and build tabs from them."""
        for title, widget in tuple(sorted(dict_of_widgets.items())):
            self.addTab(widget, title)

    def center(self):
        """Center Window on the Current Screen,with Multi-Monitor support."""
        self.showNormal()
        self.resize(QDesktopWidget().screenGeometry().width() // 1.5,
                    QDesktopWidget().screenGeometry().height() // 1.5)
        window_geometry = self.frameGeometry()
        mousepointer_position = QApplication.desktop().cursor().pos()
        screen = QApplication.desktop().screenNumber(mousepointer_position)
        centerPoint = QApplication.desktop().screenGeometry(screen).center()
        window_geometry.moveCenter(centerPoint)
        return bool(not self.move(window_geometry.topLeft()))

    def move_to_mouse_position(self):
        """Center the Window on the Current Mouse position."""
        self.showNormal()
        self.resize(QDesktopWidget().screenGeometry().width() // 1.5,
                    QDesktopWidget().screenGeometry().height() // 1.5)
        window_geometry = self.frameGeometry()
        window_geometry.moveCenter(QApplication.desktop().cursor().pos())
        return bool(not self.move(window_geometry.topLeft()))

    def set_icon(self, icon: (None, str)=None) -> str:
        """Return a string with opendesktop standard icon name for Qt."""
        if not icon:
            try:
                cur_idx = STD_ICON_NAMES.index(self.windowIcon().name())
            except ValueError:
                cur_idx = 0
            icon = QInputDialog.getItem(None, __doc__, "<b>Choose Icon name?:",
                                        STD_ICON_NAMES, cur_idx, False)[0]
        if icon:
            log.debug("Setting Tray and Window Icon name to:{}.".format(icon))
            self.tray.setIcon(QIcon.fromTheme("{}".format(icon)))
            self.setWindowIcon(QIcon.fromTheme("{}".format(icon)))
        return icon

    def make_tabs_fade(self, index):
        """Make tabs fading transitions."""
        self.fader.fade(
            self.previous_pic, self.widget(index).geometry(),
            1 if self.tabPosition() else self.tabBar().tabRect(0).height())
        self.previous_pic = self.currentWidget().grab()

    def make_undock(self):
        """Undock a Tab from TabWidget and promote to a Dialog."""
        dialog, index = QDialog(self), self.currentIndex()
        widget_from_tab = self.widget(index)
        dialog_layout = QVBoxLayout(dialog)
        dialog.setWindowTitle(self.tabText(index))
        dialog.setToolTip(self.tabToolTip(index))
        dialog.setWhatsThis(self.tabWhatsThis(index))
        dialog.setWindowIcon(self.tabIcon(index))
        dialog.setFont(widget_from_tab.font())
        dialog.setStyleSheet(widget_from_tab.styleSheet())
        dialog.setMinimumSize(widget_from_tab.minimumSize())
        dialog.setMaximumSize(widget_from_tab.maximumSize())
        dialog.setGeometry(widget_from_tab.geometry())

        def closeEvent_override(event):
            """Re-dock back from Dialog to a new Tab."""
            msg = "<b>Close this Floating Tab Window and Re-Dock as a new Tab?"
            conditional = QMessageBox.question(
                self, "Undocked Tab", msg, QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No) == QMessageBox.Yes
            if conditional:
                index_plus_1 = self.count() + 1
                self.insertTab(index_plus_1, widget_from_tab,
                               dialog.windowIcon(), dialog.windowTitle())
                self.setTabToolTip(index_plus_1, dialog.toolTip())
                self.setTabWhatsThis(index_plus_1, dialog.whatsThis())
                return event.accept()
            else:
                return event.ignore()

        dialog.closeEvent = closeEvent_override
        self.removeTab(index)
        widget_from_tab.setParent(self.parent if self.parent else dialog)
        dialog_layout.addWidget(widget_from_tab)
        dialog.setLayout(dialog_layout)
        widget_from_tab.show()
        dialog.show()  # exec_() for modal dialog, show() for non-modal dialog
        dialog.move(QCursor.pos())

    def make_tabs_previews(self, index):
        """Make Tabs Previews for all tabs except current, if > 3 Tabs."""
        if self.count() < 4 or not self.tabBar().tab_previews:
            return False  # At least 4Tabs to use preview,and should be Enabled
        if self.timer.isActive():  # Be Race Condition Safe
            self.timer.stop()
        for old_widget in self.previews:
            old_widget.close()  # Visually Hide the Previews closing it
            old_widget.setParent(None)  # Orphan the old previews
            old_widget.destroy()  # Destroy to Free Resources
        self.previews = [QLabel(self) for i in range(self.count())]  # New Ones
        y_pos = self.size().height() - self.tabBar().tabRect(0).size().height()
        for i, widget in enumerate(self.previews):  # Iterate,set QPixmaps,Show
            if i != index:  # Dont make a pointless preview for the current Tab
                widget.setScaledContents(True)  # Auto-Scale QPixmap contents
                tabwidth = self.tabBar().tabRect(i).size().width()
                tabwidth = 200 if tabwidth > 200 else tabwidth  # Limit sizes
                widget.setPixmap(self.widget(i).grab().scaledToWidth(tabwidth))
                widget.resize(tabwidth - 1, tabwidth)
                if self.tabPosition():  # Move based on Top / Bottom positions
                    widget.move(self.tabBar().tabRect(i).left() * 1.1,
                                y_pos - tabwidth - 3)
                else:
                    widget.move(self.tabBar().tabRect(i).bottomLeft() * 1.1)
                widget.show()
        self.timer.start(1000)  # how many time display the previews
        return True
Exemplo n.º 3
0
class ClientTabManager(QWidget):

    opened_tabs = []

    tab_counter = 0

    client = None

    def __init__(self, parent, clt):
        super().__init__(parent)
        self.client_layout = QVBoxLayout(self)
        self.client = clt

        # Initialize tab screen
        self.client_tabs = QTabWidget()
        self.client_tabs.setTabsClosable(False)
        self.client_tabs.tabCloseRequested.connect(self.close_tab)
        self.client_tabs.tabBarClicked.connect(lambda x: print(x))
        self.client_tabs.resize(900,600)

        # Add tabs
        self.add_tab_button = QToolButton(self)
        self.add_tab_button.setText('+')
        font = self.add_tab_button.font()
        font.setBold(True)
        self.add_tab_button.setFont(font)
        self.client_tabs.setCornerWidget(self.add_tab_button)
        self.add_tab_button.clicked.connect(self.add_tab)
        tab1 = QWidget()
        self.setup_tab(tab1)
        self.opened_tabs.append((tab1, "New Tab"))
        self.client_tabs.addTab(self.opened_tabs[0][0], self.opened_tabs[0][1])

        # Add tabs to widget
        self.client_layout.addWidget(self.client_tabs)
        self.setLayout(self.client_layout)



    def connect(self, ip, port, layout):
        #old_layout = copy.deepcopy(layout)
        deleteLayout(layout)
        try:
            self.client.connect_to_server(ip, int(port))
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)
            msg.setText("Connection successful!")
            msg.setWindowTitle("Connection info")
            msg.exec_()
            layout.addWidget(NetworkFolderManager(self, self.client))
        except FailedToConnect as e:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Error)
            msg.setText("Connection Failed!")
            msg.setInformativeText(str(e))
            msg.setWindowTitle("Connection info")
            msg.exec_()
            self.setup_tab(layout)

        except ClientAlreadyExists as e:
            msg = ReconnectDialog()
            msg.exec_();
            """msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)
            msg.setText("Connection Failed!")
            msg.setInformativeText(str(e))
            msg.setWindowTitle("Connection info")
            msg.exec_()
            self.setup_tab(layout)"""

    def setup_tab(self, tab_widget):
        tab1_layout = QVBoxLayout()

        conn_btn = QPushButton("Connect...")
        conn_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        btn_layout = QHBoxLayout()
        btn_layout.addLayout(QVBoxLayout(), 2)
        btn_layout.addWidget(conn_btn, 3)
        btn_layout.addLayout(QVBoxLayout(), 2)

        ip_layout = QHBoxLayout()
        ip_main_layout = QHBoxLayout()
        ip_label = QLabel("IP Address: ")
        ip_edit = QLineEdit()
        ip_layout.addWidget(ip_label)
        ip_layout.addWidget(ip_edit)
        ip_main_layout.addLayout(QVBoxLayout(), 2)
        ip_main_layout.addLayout(ip_layout, 3)
        ip_main_layout.addLayout(QVBoxLayout(), 2)

        port_layout = QHBoxLayout()
        port_main_layout = QHBoxLayout()
        port_label = QLabel("Port: ")
        port_edit = QLineEdit()
        port_edit.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        port_layout.addWidget(port_label)
        port_layout.addWidget(port_edit)
        port_main_layout.addLayout(QVBoxLayout(), 2)
        port_main_layout.addLayout(port_layout, 3)
        port_main_layout.addLayout(QVBoxLayout(), 2)

        tab_main = QVBoxLayout()
        tab1_layout.addLayout(ip_main_layout, 2)
        tab1_layout.addLayout(port_main_layout, 2)
        tab1_layout.addLayout(btn_layout, 2)

        tab1_layout.setSpacing(20)
        conn_btn.clicked.connect(lambda x: self.connect(ip_edit.text(), port_edit.text(), tab1_layout))

        tab_main.addLayout(QVBoxLayout(), 2)
        tab_main.addLayout(tab1_layout, 3)
        tab_main.addLayout(QVBoxLayout(), 2)
        #tab1_layout.addStretch(100)
        tab_widget.setLayout(tab_main)

    def add_tab(self):
        if not self.tab_counter:
            self.client_tabs.setTabsClosable(True)
        self.tab_counter += 1
        new_tab = (QWidget(), "New Tab")
        self.setup_tab(new_tab[0])
        self.opened_tabs.append(new_tab)
        self.client_tabs.addTab(new_tab[0], new_tab[1])

    def close_tab(self, index):
        if self.tab_counter == 1:
            self.client_tabs.setTabsClosable(False)

        # TODO: Close any client connections and do cleaning up here
        self.client_tabs.removeTab(index)
        self.tab_counter -= 1
Exemplo n.º 4
0
class BookDiary(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()
        # Initialize bookDB database
        self.memodb = []
        self.filename = 'memoDB.dat'
        self.readMemoDB()

    def initUI(self):
        # BookDiary logo label
        self.bookdiaryLabel = QLabel("DOKU")
        self.bookdiaryLabel.setAlignment(Qt.AlignCenter)
        font = self.bookdiaryLabel.font()
        font.setFamily('Courier New')
        font.setPointSize(font.pointSize() + 12)
        self.bookdiaryLabel.setFont(font)

        # Layout
        bookdiaryLayout = QGridLayout()
        bookdiaryLayout.addWidget(self.bookdiaryLabel, 0, 0)

        # Record Layout creation
        recordLayout = QGridLayout()

        # Input title widget for user
        self.title = QLabel('Title:')
        self.titleInput = QLineEdit()
        self.titleInput.setAlignment(Qt.AlignLeft)
        font = self.title.font()
        font.setPointSize(font.pointSize() + 2)
        self.title.setFont(font)
        self.titleInput.setFont(font)
        recordLayout.addWidget(self.title, 0, 0)
        recordLayout.addWidget(self.titleInput, 0, 1)

        # Input author widget for user
        self.author = QLabel('Author:')
        self.authorInput = QLineEdit()
        self.authorInput.setAlignment(Qt.AlignLeft)
        font = self.author.font()
        font.setPointSize(font.pointSize() + 2)
        self.author.setFont(font)
        self.authorInput.setFont(font)
        recordLayout.addWidget(self.author, 0, 2)
        recordLayout.addWidget(self.authorInput, 0, 3)

        # Input publisher widget for user
        self.publisher = QLabel('Publisher:')
        self.publisherInput = QLineEdit()
        self.publisherInput.setAlignment(Qt.AlignLeft)
        font = self.publisher.font()
        font.setPointSize(font.pointSize() + 2)
        self.publisher.setFont(font)
        self.publisherInput.setFont(font)
        recordLayout.addWidget(self.publisher, 0, 4)
        recordLayout.addWidget(self.publisherInput, 0, 5)

        # Button for reading Barcode
        self.barcodeButton = QToolButton()
        self.barcodeButton.setText('Barcode')
        font = self.barcodeButton.font()
        font.setPointSize(font.pointSize() + 3)
        self.barcodeButton.setFont(font)
        self.barcodeButton.clicked.connect(self.barcodeClicked)
        recordLayout.addWidget(self.barcodeButton, 0, 6)

        # Button for add records
        self.addButton = QToolButton()
        self.addButton.setText('Add')
        font = self.addButton.font()
        font.setPointSize(font.pointSize() + 3)
        self.addButton.setFont(font)
        self.addButton.clicked.connect(self.addClicked)
        recordLayout.addWidget(self.addButton, 3, 6)

        # Button for show records
        self.showButton = QToolButton()
        self.showButton.setText('Show')
        font = self.showButton.font()
        font.setPointSize(font.pointSize() + 3)
        self.showButton.setFont(font)
        self.showButton.clicked.connect(self.showClicked)
        recordLayout.addWidget(self.showButton, 1, 5)

        # Input memo widget for user
        self.memo = QLabel('Memo:')
        self.memoInput = QTextEdit()
        self.memoInput.setAlignment(Qt.AlignLeft)
        font = self.memo.font()
        font.setPointSize(font.pointSize() + 2)
        self.memo.setFont(font)
        self.memoInput.setFont(font)
        recordLayout.addWidget(self.memo, 2, 0, 1, 6)
        recordLayout.addWidget(self.memoInput, 3, 0, 1, 6)

        # Layout placement
        mainLayout = QGridLayout()
        mainLayout.setSizeConstraint(QLayout.SetFixedSize)
        mainLayout.addLayout(bookdiaryLayout, 0, 0)
        mainLayout.addLayout(recordLayout, 1, 0)

        self.setLayout(mainLayout)

        self.setWindowTitle('DOKU - Book Diary')

    def closeEvent(self, event):
        self.writeMemoDB()

    def readMemoDB(self):
        try:
            fH = open(self.filename, 'rb')
        except FileNotFoundError as e:
            self.memodb = []
            return
        try:
            self.memodb = pickle.load(fH)
        except:
            pass
        else:
            pass
        fH.close()

    # write the data into person db
    def writeMemoDB(self):
        fH = open(self.filename, 'wb')
        pickle.dump(self.memodb, fH)
        fH.close()

    def barcodeClicked(self):
        barcode = Barcode()
        connectAPI = ConnectAPI()
        books = connectAPI.search_book(barcode.readBarcode())['items']
        self.titleInput.setText(books[0]['title'])
        self.authorInput.setText(books[0]['author'])
        self.publisherInput.setText(books[0]['publisher'])

    def addClicked(self):
        record = {
            'title': self.titleInput.text(),
            'author': self.authorInput.text(),
            'publisher': self.publisherInput.text(),
            'memo': self.memoInput.toPlainText()
        }
        self.memodb += [record]
        self.showClicked()

    def showClicked(self):
        self.memoInput.clear()
        for b in self.memodb:
            if b['title'] == self.titleInput.text() and b['author'] == self.authorInput.text() and \
                    b['publisher'] == self.publisherInput.text():
                self.titleInput.setText(b['title'])
                self.authorInput.setText(b['author'])
                self.publisherInput.setText(b['publisher'])
                self.memoInput.setText(b['memo'])