class EntryView(BaseTransactionView): def _setup(self): self._setupUi() self.etable = EntryTable(self.model.etable, view=self.tableView) self.efbar = EntryFilterBar(model=self.model.filter_bar, view=self.filterBar) self.bgraph = Chart(self.model.bargraph, view=self.barGraphView) self.lgraph = Chart(self.model.balgraph, view=self.lineGraphView) self._setupColumns( ) # Can only be done after the model has been connected self.reconciliationButton.clicked.connect( self.model.toggle_reconciliation_mode) def _setupUi(self): self.resize(483, 423) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(0) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setSpacing(0) self.filterBar = RadioBox(self) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.filterBar.sizePolicy().hasHeightForWidth()) self.filterBar.setSizePolicy(sizePolicy) self.horizontalLayout.addWidget(self.filterBar) self.horizontalLayout.addItem(horizontalSpacer()) self.reconciliationButton = QPushButton(tr("Reconciliation")) self.reconciliationButton.setCheckable(True) self.horizontalLayout.addWidget(self.reconciliationButton) self.verticalLayout.addLayout(self.horizontalLayout) self.splitterView = QSplitter() self.splitterView.setOrientation(Qt.Vertical) self.splitterView.setChildrenCollapsible(False) self.tableView = TableView(self) self.tableView.setAcceptDrops(True) self.tableView.setEditTriggers(QAbstractItemView.DoubleClicked | QAbstractItemView.EditKeyPressed) self.tableView.setDragEnabled(True) self.tableView.setDragDropMode(QAbstractItemView.InternalMove) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setSortingEnabled(True) self.tableView.horizontalHeader().setHighlightSections(False) self.tableView.horizontalHeader().setMinimumSectionSize(18) self.tableView.verticalHeader().setVisible(False) self.tableView.verticalHeader().setDefaultSectionSize(18) self.splitterView.addWidget(self.tableView) self.graphView = QStackedWidget(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.graphView.sizePolicy().hasHeightForWidth()) self.graphView.setSizePolicy(sizePolicy) self.graphView.setMinimumSize(0, 200) self.lineGraphView = LineGraphView() self.graphView.addWidget(self.lineGraphView) self.barGraphView = BarGraphView() self.graphView.addWidget(self.barGraphView) self.splitterView.addWidget(self.graphView) self.graphView.setCurrentIndex(1) self.splitterView.setStretchFactor(0, 1) self.splitterView.setStretchFactor(1, 0) self.verticalLayout.addWidget(self.splitterView) def _setupColumns(self): h = self.tableView.horizontalHeader() h.setSectionsMovable(True) # column drag & drop reorder # --- QWidget override def setFocus(self): self.etable.view.setFocus() # --- Public def fitViewsForPrint(self, viewPrinter): hidden = self.model.mainwindow.hidden_areas viewPrinter.fitTable(self.etable) if PaneArea.BottomGraph not in hidden: viewPrinter.fit(self.graphView.currentWidget(), 300, 150, expandH=True, expandV=True) def restoreSubviewsSize(self): graphHeight = self.model.graph_height_to_restore if graphHeight: splitterHeight = self.splitterView.height() sizes = [splitterHeight - graphHeight, graphHeight] self.splitterView.setSizes(sizes) # --- model --> view def refresh_reconciliation_button(self): if self.model.can_toggle_reconciliation_mode: self.reconciliationButton.setEnabled(True) self.reconciliationButton.setChecked( self.model.reconciliation_mode) else: self.reconciliationButton.setEnabled(False) self.reconciliationButton.setChecked(False) def show_bar_graph(self): self.graphView.setCurrentIndex(1) def show_line_graph(self): self.graphView.setCurrentIndex(0) def update_visibility(self): hidden = self.model.mainwindow.hidden_areas self.graphView.setHidden(PaneArea.BottomGraph in hidden)
class MainWindow(QMainWindow): """ 主窗体 """ tray_icon = None # 托盘图标 base_widget = None # 界面最基础容器 base_layout = None # 界面最基础布局 left_frame = None # 界面左边容器 left_layout = None # 界面左边布局 right_frame = None # 界面右边容器 right_layout = None # 界面右边布局 option_frame = None # 功能选项容器 option_list_widget = None # 左侧功能选项 option_stack_widget = None # 右侧功能页面 log_widget = None # 右侧日志界面 log_text = None # 日志框 log_text_signal = pyqtSignal(str) def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.init_window() self.init_tray() self.log_text_signal.connect(self.append_text) threading.Thread(target=self.read_log).start() def init_window(self): """ 初始化窗体 :return: """ self.setWindowTitle("虾皮助手") self.setMinimumSize(QSize(800, 600)) self.setStyleSheet("background-color: rgb(248,248, 255)") # 基础容器定义 self.base_widget = QWidget(self) self.base_layout = QHBoxLayout() self.base_widget.setLayout(self.base_layout) self.setCentralWidget(self.base_widget) # 左边容器定义 self.left_frame = QFrame(self.base_widget) self.init_left_frame() # 右边容器定义 self.right_frame = QFrame(self.base_widget) self.init_right_frame() self.base_layout.addWidget(self.left_frame) self.base_layout.addWidget(self.right_frame) def init_left_frame(self): """ 初始化左边容器 :return: """ self.left_layout = QVBoxLayout() self.left_frame.setLayout(self.left_layout) self.left_layout.setContentsMargins(0, 0, 0, 0) self.left_frame.setContentsMargins(0, 20, 0, 0) self.left_frame.setMinimumWidth(125) self.left_frame.setMaximumWidth(125) self.left_frame.setStyleSheet("background-color: rgb(222,248, 255)") size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) size_policy.setHorizontalStretch(1) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.left_frame.sizePolicy().hasHeightForWidth()) self.left_frame.setSizePolicy(size_policy) avatar_label = AvatarLabel(image_path=AVATAR_IMAGE_PATH) self.left_layout.addWidget(avatar_label) self.option_frame = QWidget() self.option_frame.setContentsMargins(0, 30, 0, 0) option_layout = QVBoxLayout() option_layout.setContentsMargins(0, 0, 0, 0) self.option_frame.setLayout(option_layout) self.option_list_widget = QListWidget() self.option_list_widget.setContentsMargins(0, 0, 0, 0) option_layout.addWidget(self.option_list_widget) for i in range(len(OPTIONS)): item = QListWidgetItem() item.setText(OPTIONS[i]) item.setIcon( QIcon(os.path.join(OPTIONS_ICON_DIR, '{}.png'.format(i + 1)))) item.setTextAlignment(Qt.AlignCenter) item.setSizeHint(QSize(125, 25)) self.option_list_widget.addItem(item) self.option_list_widget.setFrameStyle(QListWidget.NoFrame) self.left_layout.addWidget(self.option_frame) def init_right_frame(self): """ 初始化右边容器 :return: """ self.right_layout = QVBoxLayout() self.right_layout.setContentsMargins(0, 0, 0, 0) self.right_frame.setContentsMargins(0, 0, 0, 0) self.right_frame.setLayout(self.right_layout) self.right_frame.setStyleSheet("background-color: rgb(248,248, 255)") size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) size_policy.setHorizontalStretch(4) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.right_frame.sizePolicy().hasHeightForWidth()) self.right_frame.setSizePolicy(size_policy) self.option_stack_widget = QStackedWidget() self.option_list_widget.setMinimumHeight(600) self.option_stack_widget.setContentsMargins(0, 0, 0, 0) self.option_list_widget.currentRowChanged.connect( self.option_stack_widget.setCurrentIndex) size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(10) size_policy.setHeightForWidth( self.option_stack_widget.sizePolicy().hasHeightForWidth()) for frame in FRAMES: obj = frame() self.option_stack_widget.addWidget(obj) self.log_widget = QWidget() self.log_widget.setMaximumHeight(200) self.log_widget.setContentsMargins(0, 0, 0, 0) size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(1) size_policy.setHeightForWidth( self.log_widget.sizePolicy().hasHeightForWidth()) log_layout = QVBoxLayout() log_layout.setContentsMargins(0, 0, 0, 0) self.log_widget.setLayout(log_layout) log_label = QLabel('日志记录') log_label.setContentsMargins(0, 0, 0, 0) log_label.setAlignment(Qt.AlignCenter) self.log_text = QTextBrowser() self.log_text.setContentsMargins(0, 0, 0, 0) self.log_text.setAlignment(Qt.AlignLeft) log_layout.addWidget(log_label) log_layout.addWidget(self.log_text) self.right_layout.addWidget(self.option_stack_widget) self.right_layout.addWidget(self.log_widget) @pyqtSlot(str) def append_text(self, text): self.log_text.append(text) def read_log(self): while True: while has_log(): msg = read_log() self.log_text_signal.emit(msg) time.sleep(0.05) time.sleep(0.1) def exit(self): self.tray_icon = None os._exit(0) def init_tray(self): """ 初始化系统托盘 :return: """ self.tray_icon = QSystemTrayIcon(self) self.tray_icon.setIcon(QIcon(TRAY_ICON)) show_action = QAction("显示窗口", self) quit_action = QAction("退出程序", self) hide_action = QAction("隐藏窗口", self) show_action.triggered.connect(self.show) hide_action.triggered.connect(self.hide) quit_action.triggered.connect(self.exit) tray_menu = QMenu() tray_menu.addAction(show_action) tray_menu.addAction(hide_action) tray_menu.addAction(quit_action) self.tray_icon.setContextMenu(tray_menu) self.tray_icon.show() def closeEvent(self, event): """ 重写右上角X操作的事件 :param event: :return: """ event.ignore() self.hide() self.tray_icon.showMessage("虾皮助手", "应用已收起至托盘!!!", QSystemTrayIcon.Information, 2000)
class EntryView(BaseTransactionView): def _setup(self): self._setupUi() self.etable = EntryTable(self.model.etable, view=self.tableView) self.efbar = EntryFilterBar(model=self.model.filter_bar, view=self.filterBar) self.bgraph = Chart(self.model.bargraph, view=self.barGraphView) self.lgraph = Chart(self.model.balgraph, view=self.lineGraphView) self._setupColumns() # Can only be done after the model has been connected self.reconciliationButton.clicked.connect(self.model.toggle_reconciliation_mode) def _setupUi(self): self.resize(483, 423) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(0) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setSpacing(0) self.filterBar = RadioBox(self) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filterBar.sizePolicy().hasHeightForWidth()) self.filterBar.setSizePolicy(sizePolicy) self.horizontalLayout.addWidget(self.filterBar) self.horizontalLayout.addItem(horizontalSpacer()) self.reconciliationButton = QPushButton(tr("Reconciliation")) self.reconciliationButton.setCheckable(True) self.horizontalLayout.addWidget(self.reconciliationButton) self.verticalLayout.addLayout(self.horizontalLayout) self.splitterView = QSplitter() self.splitterView.setOrientation(Qt.Vertical) self.splitterView.setChildrenCollapsible(False) self.tableView = TableView(self) self.tableView.setAcceptDrops(True) self.tableView.setEditTriggers(QAbstractItemView.DoubleClicked|QAbstractItemView.EditKeyPressed) self.tableView.setDragEnabled(True) self.tableView.setDragDropMode(QAbstractItemView.InternalMove) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setSortingEnabled(True) self.tableView.horizontalHeader().setHighlightSections(False) self.tableView.horizontalHeader().setMinimumSectionSize(18) self.tableView.verticalHeader().setVisible(False) self.tableView.verticalHeader().setDefaultSectionSize(18) self.splitterView.addWidget(self.tableView) self.graphView = QStackedWidget(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.graphView.sizePolicy().hasHeightForWidth()) self.graphView.setSizePolicy(sizePolicy) self.graphView.setMinimumSize(0, 200) self.lineGraphView = LineGraphView() self.graphView.addWidget(self.lineGraphView) self.barGraphView = BarGraphView() self.graphView.addWidget(self.barGraphView) self.splitterView.addWidget(self.graphView) self.graphView.setCurrentIndex(1) self.splitterView.setStretchFactor(0, 1) self.splitterView.setStretchFactor(1, 0) self.verticalLayout.addWidget(self.splitterView) def _setupColumns(self): h = self.tableView.horizontalHeader() h.setSectionsMovable(True) # column drag & drop reorder # --- QWidget override def setFocus(self): self.etable.view.setFocus() # --- Public def fitViewsForPrint(self, viewPrinter): hidden = self.model.mainwindow.hidden_areas viewPrinter.fitTable(self.etable) if PaneArea.BottomGraph not in hidden: viewPrinter.fit(self.graphView.currentWidget(), 300, 150, expandH=True, expandV=True) def restoreSubviewsSize(self): graphHeight = self.model.graph_height_to_restore if graphHeight: splitterHeight = self.splitterView.height() sizes = [splitterHeight-graphHeight, graphHeight] self.splitterView.setSizes(sizes) # --- model --> view def refresh_reconciliation_button(self): if self.model.can_toggle_reconciliation_mode: self.reconciliationButton.setEnabled(True) self.reconciliationButton.setChecked(self.model.reconciliation_mode) else: self.reconciliationButton.setEnabled(False) self.reconciliationButton.setChecked(False) def show_bar_graph(self): self.graphView.setCurrentIndex(1) def show_line_graph(self): self.graphView.setCurrentIndex(0) def update_visibility(self): hidden = self.model.mainwindow.hidden_areas self.graphView.setHidden(PaneArea.BottomGraph in hidden)
class Ui_MainWindow(object): def setupUi(self, MainWindow): self.MainWindow = MainWindow self.setupMainWindow() self.setupMenuBar() self.setupAjdustmentOptionBar() self.setupMainStack() self.shiftUi = Ui_ShiftWindow(self.shift_page) self.shiftUi.setupUi() self.perpetualUi = Ui_PerpetualWindow(self.perpetual_page) self.perpetualUi.setupUi() self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def setupMainWindow(self): self.MainWindow.setObjectName("MainWindow") self.MainWindow.resize(1500, 800) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.MainWindow.sizePolicy().hasHeightForWidth()) self.MainWindow.setSizePolicy(sizePolicy) self.MainWindow.setMinimumSize(QtCore.QSize(1500, 800)) self.centralWidget = QWidget(self.MainWindow) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.centralWidget.sizePolicy().hasHeightForWidth()) self.centralWidget.setSizePolicy(sizePolicy) self.centralWidget.setMinimumSize(QtCore.QSize(1500, 800)) self.centralWidget.setSizeIncrement(QtCore.QSize(5, 5)) self.centralWidget.setBaseSize(QtCore.QSize(5, 5)) self.centralWidget.setObjectName("centralWidget") self.MainWindow.setCentralWidget(self.centralWidget) self.statusBar = QStatusBar(self.MainWindow) self.statusBar.setObjectName("statusBar") self.MainWindow.setStatusBar(self.statusBar) self.toolBar = QToolBar(self.MainWindow) self.toolBar.setObjectName("toolBar") self.MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) self.outer_gridLayout = QGridLayout(self.centralWidget) self.outer_gridLayout.setSizeConstraint(QLayout.SetMinimumSize) self.outer_gridLayout.setContentsMargins(11, 6, 11, 0) self.outer_gridLayout.setSpacing(6) self.outer_gridLayout.setObjectName("outer_gridLayout") def setupMenuBar(self): self.menuBar = QMenuBar(self.MainWindow) self.menuBar.setGeometry(QtCore.QRect(0, 0, 942, 21)) self.menuBar.setObjectName("menuBar") self.MainWindow.setMenuBar(self.menuBar) self.menuLog = QMenu(self.menuBar) self.menuLog.setObjectName("menuLog") self.actionLog = QAction(self.MainWindow) self.actionLog.setObjectName("actionLog") self.menuLog.addAction(self.actionLog) self.menuBar.addAction(self.menuLog.menuAction()) _translate = QtCore.QCoreApplication.translate self.menuLog.setTitle(_translate("MainWindow", "Log")) self.actionLog.setText(_translate("MainWindow", "Show Log")) self.menuAbout = QMenu(self.menuBar) self.menuAbout.setObjectName("menuAbout") self.actionHelp = QAction(self.MainWindow) self.actionHelp.setObjectName("actionHelp") self.menuAbout.addAction(self.actionHelp) self.menuBar.addAction(self.menuAbout.menuAction()) _translate = QtCore.QCoreApplication.translate self.menuAbout.setTitle(_translate("MainWindow", "About")) self.actionHelp.setText(_translate("MainWindow", "Help")) def setupAjdustmentOptionBar(self): self.verticalWidget = QWidget(self.centralWidget) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.verticalWidget.sizePolicy().hasHeightForWidth()) self.verticalWidget.setSizePolicy(sizePolicy) self.verticalWidget.setMinimumSize(QtCore.QSize(120, 0)) self.verticalWidget.setMaximumSize(QtCore.QSize(120, 16777215)) self.verticalWidget.setStyleSheet("background-color:darkgray") self.verticalWidget.setObjectName("verticalWidget") self.verticalLayout = QVBoxLayout(self.verticalWidget) self.verticalLayout.setContentsMargins(5, 65, 5, 11) self.verticalLayout.setSpacing(20) self.verticalLayout.setObjectName("verticalLayout") self.shift_button = QPushButton(self.verticalWidget) self.shift_button.setMinimumSize(QtCore.QSize(0, 100)) font = QtGui.QFont() font.setPointSize(11) font.setBold(True) font.setWeight(75) self.shift_button.setFont(font) self.shift_button.setObjectName("shift_button") self.shift_button.setCheckable(True) self.perpetual_button = QPushButton(self.verticalWidget) self.perpetual_button.setMinimumSize(QtCore.QSize(0, 100)) font = QtGui.QFont() font.setPointSize(11) font.setBold(True) font.setWeight(75) self.perpetual_button.setFont(font) self.perpetual_button.setCheckable(True) self.perpetual_button.setObjectName("perpetual_button") self.verticalLayout.addWidget(self.shift_button) self.verticalLayout.addWidget(self.perpetual_button) self.buttonGroup = QButtonGroup(self.verticalWidget) self.buttonGroup.addButton(self.shift_button) self.buttonGroup.addButton(self.perpetual_button) self.buttonGroup.setExclusive(True) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self.verticalLayout.addItem(spacerItem) self.outer_gridLayout.addWidget(self.verticalWidget, 0, 0, 1, 1) def setupMainStack(self): self.shift_main_stacked = QStackedWidget(self.centralWidget) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.shift_main_stacked.sizePolicy().hasHeightForWidth()) self.shift_main_stacked.setSizePolicy(sizePolicy) self.shift_main_stacked.setObjectName("shift_main_stacked") self.shift_page = QWidget() sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.shift_page.sizePolicy().hasHeightForWidth()) self.shift_page.setSizePolicy(sizePolicy) self.shift_page.setObjectName("shift_page") self.shift_main_stacked.addWidget(self.shift_page) self.perpetual_page = QWidget() sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.perpetual_page.sizePolicy().hasHeightForWidth()) self.perpetual_page.setSizePolicy(sizePolicy) self.perpetual_page.setObjectName("perpetual_page") self.shift_main_stacked.addWidget(self.perpetual_page) self.outer_gridLayout.addWidget(self.shift_main_stacked, 0, 1, 1, 1) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate self.MainWindow.setWindowTitle( _translate("MainWindow", "Continuous Contract Maker")) self.shift_button.setText( _translate("MainWindow", "Forward\n" "Backward")) self.perpetual_button.setText( _translate("MainWindow", "Perputual\n" " Series")) self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))