class Test(unittest.TestCase): def setUp(self): self.world = World(None) self.world.start() def testWorld(self): self.world.loader.filename = 'ballformation.sim' self.world.loadSimulation(True) amount = len(self.world.objects) first_item = self.world.objects.keys()[0] self.world.deleteObject(first_item) amount2 = len(self.world.objects) self.assertEqual(amount-1, amount2) self.world.addObject(AstronomicalObject(vector(0,0,0), vector(0,0,0),0,sphere(position=(0,0,0), make_trail=False),0), 'newObject') self.assertEqual(len(self.world.objects), amount) self.world.close() scene.visible = 0 def testSimulation(self): self.world.loader.filename = 'ballformation.sim' self.world.loadSimulation(True) self.world.startSimulation() sleep(3) self.world.stopSimulation()
class ControlWindow(QtGui.QWidget): def __init__(self): super(ControlWindow, self).__init__() self.world = World(self) self.simulation_on = False # used to set the simulation speed display to zero if False self.add_object_window = None self.selector = None self.collision = False self.collision_text = '' self.initUI() def initUI(self): self.setGeometry(820, 30, 300, 0) self.setWindowTitle('Control Window') # create informational elements self.statusbar = QtGui.QStatusBar(self) self.statusbar.showMessage('Ready') self.sim_speed_label = QtGui.QLabel('Simulation speed: ') self.sim_speed_value = QtGui.QLabel('0 /s') velocity_scale = QtGui.QLabel('Velocity scale') acceleration_scale = QtGui.QLabel('Acceleration scale') self.reference_label = QtGui.QLabel('Default') # create control elements # buttons btn_start = QtGui.QPushButton('Start/Stop', self) btn_load = QtGui.QPushButton('Load simulation', self) btn_reload = QtGui.QPushButton('Reload simulation', self) btn_clear = QtGui.QPushButton('Clear', self) btn_camera = QtGui.QPushButton('Camera', self) # sliders velocity_vector_scale = QtGui.QSlider(QtCore.Qt.Horizontal, self) acceleration_vector_scale = QtGui.QSlider(QtCore.Qt.Horizontal, self) acceleration_vector_gain = QtGui.QSlider(QtCore.Qt.Horizontal, self) # sets the gain value for acceleration acceleration_vector_gain.setMinimum(1) acceleration_vector_gain.setMaximum(100000) # add object window self.add_object_window = AddObjectWindow(self.world) # time step settings timestep_label = QtGui.QLabel('Timestep:') self.timestep_value_label = QtGui.QLabel('{}'.format(self.world.getTimeStep())) timestep_set_button = QtGui.QPushButton('Set', self) self.timestep_edit = QtGui.QLineEdit(self) # checkboxes self.chkbx_trails = QtGui.QCheckBox('Show trails', self) self.chkbx_vectors = QtGui.QCheckBox('Show vectors', self) # set timers self.speedtimer = QtCore.QTimer() # updates the updates per second value self.speedtimer.setInterval(1000) self.speedtimer.start() # set widget layout grid = QtGui.QGridLayout() grid.addWidget(btn_start, 0, 0) grid.addWidget(btn_load, 0, 1) grid.addWidget(btn_reload, 0, 2) grid.addWidget(btn_clear, 0, 3) grid.addWidget(self.sim_speed_label, 1, 0) grid.addWidget(self.sim_speed_value, 1, 1) grid.addWidget(timestep_label, 3,0) grid.addWidget(self.timestep_value_label, 3, 1) grid.addWidget(self.timestep_edit, 3, 2) grid.addWidget(timestep_set_button, 3, 3) grid.addWidget(self.chkbx_trails, 4,0) grid.addWidget(btn_camera, 4, 2) grid.addWidget(self.reference_label, 4, 3) grid.addWidget(self.chkbx_vectors, 4, 1) grid.addWidget(velocity_scale, 6,0) grid.addWidget(velocity_vector_scale, 6,1) grid.addWidget(acceleration_scale, 7, 0) grid.addWidget(acceleration_vector_scale, 7, 1) grid.addWidget(acceleration_vector_gain, 7, 2) grid.addWidget(self.add_object_window,8,0,1,-1) grid.addWidget(self.statusbar, 9,0,1,-1) self.setLayout(grid) # set button tooltips btn_start.setToolTip('Start/pause simulation') timestep_set_button.setToolTip('Set simulation timestep') btn_clear.setToolTip('Clear all objects') # connect controls btn_load.clicked.connect(self.loadSimulation) btn_reload.clicked.connect(self.reloadSimulation) btn_start.clicked.connect(self.startStop) btn_clear.clicked.connect(self.clearObjects) btn_camera.clicked.connect(self.openObjectSelector) self.chkbx_trails.stateChanged.connect(self.showTrails) self.chkbx_vectors.stateChanged.connect(self.showVectors) timestep_set_button.clicked.connect(self.setTimeStep) velocity_vector_scale.valueChanged.connect(self.world.setVelocityVectorScale) acceleration_vector_scale.valueChanged.connect(self.world.setAccelerationVectorScale) acceleration_vector_gain.valueChanged.connect(self.world.setAccelerationGain) # connect timer self.speedtimer.timeout.connect(self.setSimSpeedDisplay) # set visible self.show() def start(self): # call the start method of the World object to start the thread self.world.start() def setTimeStep(self): try: self.world.setTimeStep(str(self.timestep_edit.text())) except ValueError: self.statusbar.showMessage('Invalid argument for timestep') return self.timestep_value_label.setText(self.timestep_edit.text()) self.statusbar.showMessage('Ready') def setSimSpeedDisplay(self): if self.simulation_on: self.sim_speed_value.setText('{} /s'.format(self.world.speed)) else: self.sim_speed_value.setText('0 /s') if self.collision: self.collision = False self.statusbar.showMessage(self.collision_text) def loadSimulation(self): self.simulation_on = False self.world.stopSimulation() self.add_object_window.setReference('Default') self.world.loadSimulation() if self.world.errors == Loader.ERRORS_OCCURRED: self.statusbar.showMessage('Errors occurred when loading simulation. Check error log.') elif self.world.errors == Loader.OBJECTS_LOADED: self.statusbar.showMessage('Simulation loaded succesfully!') elif self.world.errors == Loader.OBJECTS_NOT_LOADED: self.statusbar.showMessage('Object loading canceled.') def reloadSimulation(self): self.simulation_on = False self.world.stopSimulation() self.add_object_window.setReference('Default') self.setReference('Default') self.world.reloadSimulation() if self.world.errors == Loader.ERRORS_OCCURRED: self.statusbar.showMessage('Errors occurred when loading simulation. Check error log.') elif self.world.errors == Loader.OBJECTS_LOADED: self.statusbar.showMessage('Simulation loaded succesfully!') elif self.world.errors == Loader.OBJECTS_NOT_LOADED: self.statusbar.showMessage('Object loading canceled.') elif self.world.errors == Loader.FILE_NOT_OPENED: self.statusbar.showMessage('File could not be loaded.') def clearObjects(self): if not self.world.paused: self.world.stopSimulation() self.simulation_on = False self.world.clearObjects() self.add_object_window.setReference('Default') self.setReference('Default') self.statusbar.showMessage('Objects cleared') def showTrails(self, state): if state == QtCore.Qt.Checked: self.world.showTrails(True) else: self.world.showTrails(False) def showVectors(self, state): if state: self.world.showVectors(True) else: self.world.showVectors(False) def startStop(self): # start/pause simulation if not self.world.paused: self.world.stopSimulation() self.simulation_on = False self.statusbar.showMessage('Simulation paused') print self.world.time_elapsed/86400 else: self.world.startSimulation() self.simulation_on = True self.statusbar.showMessage('Simulation started') def reportCollision(self, error): #self.statusbar.showMessage(error) self.collision_text = error self.collision = True self.simulation_on = False def openObjectSelector(self): self.selector = ObjectSelector(self) def setReference(self, reference): if reference != 'Default': self.world.setReference(reference) self.reference_label.setText(reference) else: self.world.setReference(None) self.reference_label.setText('Default') def closeEvent(self, event): # handle closing the program scene.visible = 0 # close the scenery window self.world.close() self.add_object_window.close() # this is necessary so that the reference selector will also close automatically if self.selector is not None: self.selector.close() self.close() event.accept()