Расчесывание внешнего цикла обработки событий с помощью Qt

Причина в том, что PDPageContentStream.showText(String) может только показывать текст , он не может выполнять никаких дополнительных макетов, например, интерпретировать горизонтальные вкладки, разрывы строк или другие управляющие символы; Тильман подробно объяснил это в своем ответе.

Вы могли бы достичь своей цели примерно следующим образом:

contentStream.newLineAtOffset(xPosition, yPosition);
contentStream.showText("Member #: "+ student.getMembershipNumber());
contentStream.newLineAtOffset(200, 0);
contentStream.showText("Grade: " + getStudentGradeInSchool(student.getYearGraduate()));
contentStream.newLineAtOffset(200, 0);
contentStream.showText("Year Joined: " + student.getYearJoined());
contentStream.newLineAtOffset(-400, -12);
contentStream.showText("Name: " + student.getFirstName() + " " + student.getLastName());
contentStream.newLineAtOffset(0, -12);
contentStream.showText("Amount Owed: $" + student.getAmountOwed());
30
задан Neil G 2 September 2017 в 20:15
поделиться

2 ответа

I haven't done too much Qt development recently, but if I remember correctly, you can call QApplication::processEvents() within your own event loop (instead of starting the Qt main loop through QApplication::exec())

Edit: I have used the opportunity of a slow Sunday morning to test-drive / learn something about PyQt (Python bindings for Qt) and cobbled together a proof-of-concept code below. Replacing the call to QApplication::exec() with a custom event loop based on QApplication::processEvents() seems to work.

I have also quickly looked at simpleeventloop.cpp and tpclient-cpptext main.cpp. From the looks of it, it shoud be fine to just add QApplication::processEvents() somewhere in the main loop of SimpleEventLoop::runEventLoop(). To add it to the main loop, I would probably replace the tv interval for the select() function in lines 106 through 117 with

tv.tv_sec = 0;
tv.tv_usec = 10000;   // run processEvents() every 0.01 seconds
app->processEvents();

and change the signature in line 89 to void SimpleEventLoop::runEventLoop(QApplication *app). It should than be fine to add your usual Qt stuff to your implementation of the client (your replacement of tpclient-cpptext main.cpp)

Looks like a hack, though. I would probably start with something like this to get started. I think that your idea of wrapping TPSocket and the timer within Qt's respective concepts in order to forward them with the QAbstractEventDispatcher to the QEventLoop is the better long-term solution. It should then be sufficient that your runEventLoop() simply calls QApplication::exec(). But I have never used QAbstractEventDispatcher before, so take my comments for what they are.

import sys
import time

from PyQt4 import QtGui
from PyQt4 import QtCore

# Global variable used as a quick and dirty way to notify my
# main event loop that the MainWindow has been exited
APP_RUNNING = False

class SampleMainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self)
        global APP_RUNNING
        APP_RUNNING = True

        # main window
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Test')
        self.statusBar().showMessage('Ready')

        # exit action (assumes that the exit icon from
        # http://upload.wikimedia.org/wikipedia/commons/b/bc/Exit.png
        # is saved as Exit.png in the same folder as this file)
        exitAction = QtGui.QAction(QtGui.QIcon('Exit.png')
                                   ,'Exit'
                                   ,self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        self.connect(exitAction
                     ,QtCore.SIGNAL('triggered()')
                     ,QtCore.SLOT('close()'))

        # main menu
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAction)

        # toolbar
        self.toolbar = self.addToolBar('Exit')
        self.toolbar.addAction(exitAction)

        # text editor
        textEdit = QtGui.QTextEdit()
        self.setCentralWidget(textEdit)

        #tool tip
        textEdit.setToolTip('Enter some text')
        QtGui.QToolTip.setFont(QtGui.QFont('English', 12))

    def closeEvent(self, event):
        reply = QtGui.QMessageBox.question(self
                                           ,'Message'
                                           ,"Are you sure?"
                                           ,QtGui.QMessageBox.Yes
                                           ,QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
            global APP_RUNNING
            APP_RUNNING = False
        else:
            event.ignore()

# main program
app = QtGui.QApplication(sys.argv)
testWindow = SampleMainWindow()
testWindow.show()
# run custom event loop instead of app.exec_()
while APP_RUNNING:
    app.processEvents()
    # sleep to prevent that my "great" event loop eats 100% cpu
    time.sleep(0.01)
33
ответ дан 28 November 2019 в 00:16
поделиться

I would probably code the event loops to be separate threads. You can handle the events from the library in a class, and have it generate signals which will then be handled by the main Qt eventloop whenever you want (call QApplication::processEvents() if needed in long operations). The only trick to this is making sure that your external event loop is a Q_OBJECT so that it knows how to emit the signals that you care about.

There are other thread issues, such as never (ever) painting in a thread which is not the main QT thread.

2
ответ дан 28 November 2019 в 00:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: