По умолчанию QThread
имеет цикл событий, который может обрабатывать сигналы и слоты. В вашей текущей реализации вы, к сожалению, устранили это поведение, переопределив QThread.run
. Если вы его восстановите, вы сможете получить желаемое поведение.
Итак, если вы не можете переопределить QThread.run()
, как вы выполняете потоки в Qt? Альтернативный подход к потоковой передаче состоит в том, чтобы поместить ваш код в подкласс QObject
и перенести этот объект на стандартный экземпляр QThread
. Затем вы можете соединить сигналы и слоты между основным потоком и QThread
для связи в обоих направлениях. Это позволит вам реализовать желаемое поведение.
В приведенном ниже примере я начал рабочий поток, который печатает на терминал, ждет 2 секунды, снова распечатывает и ждет ввода пользователя. Когда кнопка нажата, выполняется вторая отдельная функция в рабочем потоке и печатает на терминал в том же шаблоне, что и в первый раз. Обратите внимание на порядок, в котором я использую moveToThread()
и подключаю сигналы (согласно этому ).
Код:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import time
class MyWorker(QObject):
wait_for_input = pyqtSignal()
done = pyqtSignal()
@pyqtSlot()
def firstWork(self):
print 'doing first work'
time.sleep(2)
print 'first work done'
self.wait_for_input.emit()
@pyqtSlot()
def secondWork(self):
print 'doing second work'
time.sleep(2)
print 'second work done'
self.done.emit()
class Window(QWidget):
def __init__(self, parent = None):
super(Window, self).__init__()
self.initUi()
self.setupThread()
def initUi(self):
layout = QVBoxLayout()
self.button = QPushButton('User input')
self.button.setEnabled(False)
layout.addWidget(self.button)
self.setLayout(layout)
self.show()
@pyqtSlot()
def enableButton(self):
self.button.setEnabled(True)
@pyqtSlot()
def done(self):
self.button.setEnabled(False)
def setupThread(self):
self.thread = QThread()
self.worker = MyWorker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.firstWork)
self.button.clicked.connect(self.worker.secondWork)
self.worker.wait_for_input.connect(self.enableButton)
self.worker.done.connect(self.done)
# Start thread
self.thread.start()
if __name__ == "__main__":
app = QApplication([])
w = Window()
app.exec_()
Итак, заполнение базы данных - это процесс, в котором начальный набор данных предоставляется базе данных.
В качестве передового опыта вместо ручной вставки данных следует настроить начальные данные для автоматической вставки документов.
var seeder = require('mongoose-seed');
// Connect to MongoDB via Mongoose
seeder.connect('mongodb://localhost/yourDatabase', function() {
// Load Mongoose models
seeder.loadModels([
'models/roles.js'
]);
// Clear specified collections
seeder.clearModels(['roles'], function() {
// Callback to populate DB once collections have been cleared
seeder.populateModels(data, function() {
seeder.disconnect();
});
});
});
// Data array containing seed data - documents organized by Model
var data = [
{
'model': 'role',
'documents': [
{
'role': 'user',
'value': ['readPost', 'commentPost', 'votePost']
},{
'role': 'another role',
'value': ['updatePost', 'deletePost']
}
]
}
];
поместите этот код в файл seed.js
и запустите его.
Предполагая, что имена ролей уникальны, вы действительно можете запросить базу данных и проверить, существует ли уже роль с таким именем. Если нет, мы идем вперед и создаем роль.
Это хорошо работает для меня:
const createRole = async ({role, permissions}) => {
const matches = await RoleModel.find({role}).exec();
if (matches.length === 0) {
return RoleModel.create({role, permissions});
}
};
Затем метод может быть вызван следующим образом (, если вы уже подключились к базе данных ):
const userRole = {
role: "User",
permissions: ["readPost", "commentPost", "votePost"]
};
(async () => {
await createRole(userRole);
console.log("User role has been created successfully.");
})()