【问题标题】:Barcode scanning with PyQt5使用 PyQt5 进行条码扫描
【发布时间】:2020-08-04 20:29:59
【问题描述】:

我有一个 USB 条形码扫描仪,我正在连接到我的计算机。每次扫描条形码时,它都会像键盘一样将数据输入计算机。我的目标是将数据输入到 PyQT5 Table 小部件中。

我已经创建了下表,我只是将项目扫描到其中。问题是当我扫描一个项目时,它会编辑第一个单元格,但光标不会自动移动到下一行,因此我可以将新项目扫描到表中。我必须单击第二个单元格,然后扫描该项目。然后单击第三个单元格并扫描项目,依此类推。

我想知道如何实现自动化,以便在将项目扫描到第一个单元格后,它会自动移动到下一个单元格并等待来自扫描仪的输入?

import sys 
from PyQt5.QtWidgets import * 
   
#Main Window 
class App(QWidget): 
    def __init__(self): 
        super().__init__() 
        self.title = 'Specimen Dashboard'

        self.setWindowTitle(self.title)    
        self.tableWidget = QTableWidget() 
        self.createTable() 
        self.tableWidget.itemChanged.connect(self.go_to_next_row) 
   
        self.layout = QVBoxLayout() 
        self.layout.addWidget(self.tableWidget) 
        self.setLayout(self.layout) 

        self.show() 
   
    def go_to_next_row(self):
        #Not working
        #Trying to see if I can automatically move to next cell, but editing it 
        self.tableWidget.setItem(1,0, QTableWidgetItem("Name")) 

    #Create table 
    def createTable(self):   
        self.tableWidget.setRowCount(4)  
        self.tableWidget.setColumnCount(2)   
        self.tableWidget.horizontalHeader().setStretchLastSection(True) 
        self.tableWidget.horizontalHeader().setSectionResizeMode( 
            QHeaderView.Stretch) 

app = QApplication(sys.argv) 
ex = App() 
sys.exit(app.exec_()) 

【问题讨论】:

  • AFAIK,一旦代码被扫描,它还应该发送一个确认/换行符(在你的情况下,它会退出单元格的编辑模式),对吧?
  • 我不知道为什么它会立即关闭。在excel中,它工作正常。我扫描,它写入单元格并自动移动到下一个单元格。在 PyQt5 中,当它遇到换行符时,它只是停留在当前单元格上
  • 我没有问你这个。我想知道扫描仪是否在每次扫描后发送一个类似返回的字符。
  • 它编辑单元格并保留在单元格上,并以蓝色突出显示。如果我立即扫描不同的代码,它会自动编辑同一个单元格。所以就好像我按下了 Enter 键。每次扫描后它都会发送一个类似返回的字符。

标签: python pyqt pyqt5 barcode-scanner


【解决方案1】:

默认情况下,扫描器会发送一个 endline("\n"),它被转换为 Return 或 Enter 键,默认情况下会关闭编辑器,在这种情况下必须拦截该事件,移动光标并打开编辑器:

import sys

from PyQt5 import QtCore, QtWidgets


class TableWidget(QtWidgets.QTableWidget):
    def keyPressEvent(self, event):
        if (
            event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return)
            and self.state() == QtWidgets.QAbstractItemView.EditingState
        ):
            index = self.moveCursor(
                QtWidgets.QAbstractItemView.MoveNext, QtCore.Qt.NoModifier
            )
            self.selectionModel().setCurrentIndex(
                index, QtCore.QItemSelectionModel.ClearAndSelect
            )
            self.edit(index)
        else:
            super().keyPressEvent(event)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.tableWidget = TableWidget(4, 2)
        self.setCentralWidget(self.tableWidget)
        self.tableWidget.horizontalHeader().setStretchLastSection(True)
        self.tableWidget.horizontalHeader().setSectionResizeMode(
            QtWidgets.QHeaderView.Stretch
        )


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

【讨论】:

  • 我想说你还应该检查state() == self.EditingState,否则在没有打开任何编辑器的情况下按键盘上的回车键会开始编辑下一个项目。
  • @musicamante 你说得对,谢谢你指出
【解决方案2】:

您可以对表进行子类化并覆盖closeEditor()hint 参数告诉视图当编辑器关闭时应该发生什么;默认情况下,按下 Enter 时会提交当前单元格数据,但您可以像这样覆盖此行为:

from PyQt5 import QtGui, QtWidgets

class Table(QtWidgets.QTableView):
    # leave to False for the default behavior (the next cell is the one at the
    # right of the current, or the first of the next row; when set to True it
    # will always go to the next row, while keeping the same column
    useNextRow = False

    def closeEditor(self, editor, hint):
        if hint == QtWidgets.QAbstractItemDelegate.SubmitModelCache:
            if self.useNextRow:
                super().closeEditor(editor, hint)
                current = self.currentIndex()
                newIndex = current.sibling(current.row() + 1, current.column())
                if newIndex.isValid():
                    self.setCurrentIndex(newIndex)
                    self.edit(newIndex)
                return
            else:
                hint = QtWidgets.QAbstractItemDelegate.EditNextItem
        super().closeEditor(editor, hint)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    test = Table()
    test.show()
    model = QtGui.QStandardItemModel(10, 5)
    test.setModel(model)
    sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 2021-04-05
    • 2012-07-17
    • 2014-11-04
    • 2022-11-08
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多